近来学三大框架,因此学了反射和动态代理,这篇来回头想一想关于反射Reflection。
为什么会有反射?
假如你在程序运行过程中,从磁盘上或者从网络上读取接收了一串代表一个类的字节,既然这个类在你的程序被编译很久之后才出现,那么你怎样使用这样的类呢?
解决:Class类和java.lang.reflect类库一起对反射的概念进行了支持。
下面讲的Class类将不仅仅局限在反射这个概念上:
Class类:
每个类和接口都有且仅有一个Class类型的对象,它由JVM自行创建,并且仅加载一次。每个类每个对象的创建都依赖于该类的Class类型对象。
如何获得一个类的Class对象?分为两种情况:
一:如果该类在编译前就已知。也就是该类在classPath路径下。这就是RTTI。
1)Class c = 类名.Class
2)Class c = Class.forName(String className)
二:如果该类编译器未知,也就是在程序运行时才知道的。这就是反射
1)Class c = Class.forName(String arg[0])
java.lang.reflect类库:
改类库中的Field类提供获取该不确定类中的字段的api
Class> c = Class.forNmae(Stringarg[0]);
Field[] fields = c.getFields();
该类库中的Method类提供获取该不确定类中的方法的api
Method[] methods = c.get Methods()
该类库中的Constructor类提供获取该不确定类中的构造器的api
Constructor []constructor= c.getConstructors()
注:想了解更多实用api请自行search for jdk文档
我们现在再来想为什么要有反射?
我们看我们遇到的问题是什么?在编译时编译器不知道某个特定类的信息,本质是编译时无法获得并打开特定类的.class文件,而是在程序运行起来时jvm才拥有该特定类的.class文件。那么,如何使用这样的文件呢?于是“反射”这个概念应运而生---提供在运行时操作.class文件的统一API。
所以,我们要认识到反射机制并没有什么神奇之处。反射与RTTI的本质区别只是检查一个类的.class文件的时机不同:
反射:.class 文件是在编译时不可获得的,所以在运行时打开和检查未知类的.class文件从而变已知。
RTTI: .class 文件是在编译时打开和检查。