什么是反射

反射机制允许在Java代码中获取被JVM加载的类信息,如:成员变量,方法,构造函数等。

在Java包java.lang.reflect下提供了获取类和对象反射信息的相关工具类和接口,如:Field,Method,Constructor等。

使用反射可以做什么事情

反射通常被用于需要检查或修改应用程序运行时行为的编程中,它是一个非常有用的技术。

具体来讲,可以在如下场景中使用反射机制:

  • 功能扩展,应用程序可以通过反射创建一个具备完整限定名的类实例,从而使用一个外部的用户自定义的类。
  • 在可视化的开发环境中浏览类信息,其实在eclipse中通过快捷键Ctrl + O显示的类信息就是利用反射机制实现的。
  • 用于程序调试器和测试工具

反射的缺点

虽然反射机制可以增强应用程序的功能和使用场景,但并非在任何情况下都适合使用的,因为反射机制本身存在一些固有的缺点。

  1. 性能损耗,反射需要动态解析类型,相比起不使用反射的情况是存在性能损耗的,所以在性能比较敏感或重要的应用程序中不要使用反射。
  2. 安全限制,反射需要的运行时权限在安全管理器(SecurityManager)下是被禁止的,比Applet程序中。
  3. 类结构被暴露,由于反射允许在非反射代码中执行一些非法操作,打破了Java原本的抽象模型,可能会影响到平台的行为与升级。

应用实践

/**
* 利用反射机制获取被JVM加载的类信息,实例化类对象。
* @desc org.chench.test.java.UserReflector
* @author chench9@lenovo.com
* @date 2017年11月30日
*/
public class UserReflector {
public static void main(String[] args) throws Exception {
String className = "org.chench.test.java.User"; // 通过类的完整限定名获取其Class对象
Class<?> userClass = Class.forName(className); // 使用反射机制获取类的构造函数列表
Constructor[] constructorArr = userClass.getConstructors();
for(Constructor constructor : constructorArr) {
// 构造函数的名称
String name = constructor.getName();
System.out.println("constructor name: " + name); // 构造函数的参数个数
int count = constructor.getParameterCount();
System.out.println("constructor parameter count: " + count); // 构造函数的参数列表
Parameter[] parameters = constructor.getParameters();
for(Parameter parameter : parameters) {
// 获取参数类型
Class<?> parameterType = parameter.getType();
// 获取参数名
String parameterName = parameter.getName();
System.out.println(parameterName + " Type: " + parameterType);
} // 通过构造函数实例化类对象
if(count <= 0) {
User user = (User) constructor.newInstance();
System.out.println("user instance: " + user);
}else if(count == 1) {
User user = (User) constructor.newInstance(new Object[] {"Zhang San"});
System.out.println("user instance: " + user);
}else if(count == 2) {
User user = (User) constructor.newInstance(new Object[] {"Li Si", 26});
System.out.println("user instance: " + user);
}
System.out.println("----------");
} // 使用反射机制获取类的成员变量
Field[] fields = userClass.getDeclaredFields();
for(Field field : fields) {
// 变量类型
Class<?> fieldType = field.getType();
// 变量名称
String fieldName = field.getName();
// 变量修饰符,private:2,public:1, protected: 4,默认类型: 0
int fieldModifier = field.getModifiers();
System.out.println("field info, name: " + fieldName + ", type: " + fieldType + ", modifier: " + fieldModifier);
} // 使用反射机制获取类的方法
Method[] methods = userClass.getDeclaredMethods();
for(Method method : methods) {
// 方法返回值类型
Class<?> returnType = method.getReturnType();
// 方法名
String methodName = method.getName();
// 方法参数个数
int count = method.getParameterCount();
System.out.println("method info, name: " + methodName + ", return type: " + returnType + ", parameter count: " +count);
}
}
}

实际上,在应用编程中使用反射机制最多的场景主要是如下2个方面:

  1. 在注解解析器中通过反射获取类,方法或成员变量的注解信息。
  2. 在动态代理类中使用反射机制调用方法执行。

【参考】

https://docs.oracle.com/javase/tutorial/reflect/TOC.html

细说java系列之反射的更多相关文章

  1. 细说java系列之注解

    写在前面 Java从1.5版本之后开始支持注解,通过注解可以很方便地实现某些功能,使用得最普遍的就是Spring框架的注解,大大简化了Bean的配置. 注解仅仅是一种Java提供的工具,并不是一种编程 ...

  2. 细说java系列之泛型

    什么是范型 简言之,范型是Java支持在编译期进行类型检查的机制. 这里面包含2层含义:其一,可以使用范型进行类型检查:其二,在编译期进行类型检查. 那么,什么叫做在编译期进行类型检查?可以在运行时进 ...

  3. 细说java系列之HashMap原理

    目录 类图 源码解读 总结 类图 在正式分析HashMap实现原理之前,先来看看其类图. 源码解读 下面集合HashMap的put(K key, V value)方法探究其实现原理. // 在Hash ...

  4. Java系列笔记(2) - Java RTTI和反射机制

    目录 前言 传统的RTTI 反射 反射的实现方式 反射的性能 反射与设计模式 前言 并不是所有的Class都能在编译时明确,因此在某些情况下需要在运行时再发现和确定类型信息(比如:基于构建编程,),这 ...

  5. Java内功修炼系列一反射

    “JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制 ...

  6. JAVA基础系列:反射

    1. 定义 在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这 种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. ...

  7. Java系列笔记(3) - Java 内存区域和GC机制

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  8. Java系列笔记(1) - Java 类加载与初始化

    目录 类加载器 动态加载 链接 初始化 示例 类加载器 在了解Java的机制之前,需要先了解类在JVM(Java虚拟机)中是如何加载的,这对后面理解java其它机制将有重要作用. 每个类编译后产生一个 ...

  9. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

随机推荐

  1. Codeforces Round #502 (in memory of Leopoldo Taravilse, Div. 1 + Div. 2)

    第一次参加cf的比赛 有点小幸运也有点小遗憾 给自己定个小目标 1500[对啊我就是很菜qvq A. The Rank 难度:普及- n位学生 每个学生有四个分数 然鹅我们只需要知道他的分数和 按分数 ...

  2. Write less code

    If you find yourself writing a lot of code to do something simple, you're probably doing it wrong. A ...

  3. Codeforces Round #554 ( div.2 ) 总结

    应该经常需要锻炼一下英语阅读理解能力和代码能力,所以以后还是需要多打打CF. 今天大概就是水一水找找感觉. A. Neko Finds Grapes $n$个箱子,$m$个钥匙 ($n,m \leq ...

  4. JS日期选择器

    浏览器自带 浏览器自带日期控件,使用<input type="date">时,点击后会弹出. 1:EDGE 2:火狐 3:谷歌  三种都不一样.略胜于无 练习 模仿火狐 ...

  5. 诶西,JavaScript学习记录。。。。。。

    由于大学课程缘故,老师巨爱叫人问问题,还记分呢,随便记录一下Js的学习情况,以后复习什么的也比较方便吧...... 开始咯,就按照C语言学习那样的方法来吧! ===================== ...

  6. 英语考试 FZU - 2254 (最小生成树)

    先选一个单词出来完全自己背,然后从这个单词到其他各个单词所需要的精力看成距离,然后用最小生成树把这些单词连接起来,就是通过我现在选的这个单词到其他各个单词的最小精力,然后再加上把这个单词背起来的精力, ...

  7. 20165223 结对编程之四则运算week2-整体总结

    目录 一.结对对象 二.需求分析 三.设计思路 四.核心代码 五.功能截图 六.结对感受 一.结对对象 担任角色(本周交换角色,流动学习) 驾驶员(Driver):20165218 赵冰雨(是控制键盘 ...

  8. RAP Mock.js语法规范

    Mock.js 的语法规范包括两部分: 数据模板定义规范(Data Template Definition,DTD) 数据占位符定义规范(Data Placeholder Definition,DPD ...

  9. 第二十九篇-Fragment动态用法

    效果图: 上节学习了静态添加Fragment的方法,这节学习动态添加方法. 主页面 layout.xml Fragment页面 layout2.xml 实现功能,当点击主页面的button时,将Fra ...

  10. RJ45连接器

    http://www.huilyn.com/path315.html      HBJ-6308ANLF http://www.hanrun.com/en/           HR971169C h ...