反射的本质
Java 在运行时能够获得或判断某个对象的类型信息
RTTI 有一条前提就是某个对象的类型信息在编译时必须已知。RTTI 的实质就是编译器在遍历检查代码时偷偷将类型信息记录下来并存储,以在运行时能够获得当编写完某个.java 文件,并编译之后,就会产生一个 Class 对象,由编译器偷偷的把这个 class 对象保存在编译后的.class 文件中,当这个.class 文件被加载到内存之后,随之会在内存中创建这个 Class 对象了。所以,获得 class 对象的前提是能获得类编译后的.class 文件。且 class 对象的功能强大,方法众多:Class.getInterfaces()、Class.getSuperclass()、Class.getName()、Class.isInterface() 等等,能用来获得很多信息
RTTI 与反射在最底层的思想上是很类似的,本质的区别在于:对 RRTI,编译器在编译时打开和检查.class 文件,而对反射来说,.class 文件在编译时是不可获取的,在运行时未知对象已经来了再去打开和检查.class 文件
反射机制使得 java 能够创建一个在编译时完全未知的对象。反射在 Java 中用来支持其他特性的,例如对象的序列化和 JavaBean
Class 对象
Class 对象是进行反射操作的入口, 所以首先必须获得 Class 对象。除了通过实例获取外,Class 对象主要由以下几种方法获得:
通过类加载器加载 class 文件
Class<?> clazz = Thread.currentThread().getContextClassLoader().
loadClass(“com.takumiCX.reflect.ClassTest”);
通过静态方法 Class.forName() 获取, 需要传入类的全限定名字符串作参数(在获得 class 对象的同时会引起类的初始化)
Class<?> clazz = Class.forName(“com.takumiCX.reflect.ClassTest”);
通过类.class 获得类的 Class 对象
Class<ClassTest> clazz = ClassTest.class;