http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
这其中有一部分对反射机制的应用,以下是我通过观看视频与阅读文献得到自己的总结:
l Java反射机制是在运行状态中,对任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意(包括私有)一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java的反射机制。
l 要解剖一个类,必须先获取到该类的字节码文件对象(通过字节码对象返回到类内的所有内容:构造方法、成员变量、成员方法)。而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型对象。所有的class文件都是该Class类的一个对象。
获取class文件对象的方式(以下方式自选一种,2比较方便,3开发用,用字符串,可配置到配置文件中):
相同的class,其文件对象都是同一个,就是说同一个类的不同对象产生的getClass()都是相同的
- Object中的getClass(), Class c=person.getClass()
- 数据类型(包括基本类型、自定义类、系统类)的静态属性class, Class c=person.class
- Class类中的静态方法forName(String className)://该className必须为全路径,也就是上文所提到的全限定名
public static Class forName(String className)
通过反射获得类的Contructor
1.返回所有公有构造方法
2.返回所有构造方法
3.获取单个构造方法
上述方法只拿公有构造器
注意:参数传入的是Class类型(如String.class,int.class等),是可变参数列表,所以可以你任意给多个。
可拿所有构造器(包括私有,但是访问私有时需要调用Constructor的setAccessible):
所谓的Constructor是构造方法对象,可用其中的newInstance(Object… targs),可用其产生该Constructor对应的构造方法对应的对象,得到的对应就是该Constructor所在类的对象。
获取成员变量或成员方法都可以通过上述类似方法,提一下对成员变量修改值的方式:
其余不赘述。
反射存在的意义就是可以通过对象反射到类和类中的一切内容,或者通过类得到对象,不需要指定也不需要知道类名等,这一切都可以通过相同的代码运行配置文件运行,代码复用方便也灵活。
配置文件一般是通过key=value的形式存储的,如
Java通过Properties类读取,
通过反射可以越过泛型检查
比如向ArrayList对象中添加String类型对象,泛型是给编译器看的,只是在编译期检查,当运行后对应的泛型是会被擦除的,如:
而该端代码在运行期后的字节码反编译后结果为(运行期的代码):
泛型被擦除了,add方法通过Integer.valueOf的方式添加Integer对象,而此时ArrayList到底可以添加什么类型的对象呢?看ArrayList源码:
说明ArrayList中是支持Object类型对象的,那么就是说听过反射是可以添加String对象的,那么如何呢?还是跟上述一样,获取到ArrayList的Class对象然后得到Method,通过反射添加String对象:
反射实现动态代理
InvocationHandler接口和Proxy类。