反射的本质

  1. Java在运行时能够获得或判断某个对象的类型信息
  2. RTTI有一条前提就是某个对象的类型信息在编译时必须已知。RTTI的实质就是编译器在遍历检查代码时偷偷将类型信息记录下来并存储,以在运行时能够获得当编写完某个.java文件,并编译之后,就会产生一个Class对象,由编译器偷偷的把这个class对象保存在编译后的.class文件中,当这个.class文件被加载到内存之后,随之会在内存中创建这个Class对象了。所以,获得class对象的前提是能获得类编译后的.class文件。且class对象的功能强大,方法众多:Class.getInterfaces()、Class.getSuperclass()、Class.getName()、Class.isInterface()等等,能用来获得很多信息
  3. RTTI与反射在最底层的思想上是很类似的,本质的区别在于:对RRTI,编译器在编译时打开和检查.class文件,而对反射来说,.class文件在编译时是不可获取的,在运行时未知对象已经来了再去打开和检查.class文件
  4. 反射机制使得java能够创建一个在编译时完全未知的对象。反射在Java中用来支持其他特性的,例如对象的序列化和JavaBean

Class对象

Class对象是进行反射操作的入口,所以首先必须获得Class对象。除了通过实例获取外,Class对象主要由以下几种方法获得:

  • 通过类加载器加载class文件
Class<?> clazz = Thread.currentThread().getContextClassLoader().
        loadClass("com.takumiCX.reflect.ClassTest");
  • 通过静态方法Class.forName()获取,需要传入类的全限定名字符串作参数(在获得class对象的同时会引起类的初始化;如果指定参数initialize为false时,也不会触发类初始化,其实这个参数是告诉虚拟机,是否要对类进行初始化)
Class<?> clazz = Class.forName("com.takumiCX.reflect.ClassTest");
  • 通过类.class获得类的Class对象
Class<ClassTest> clazz = ClassTest.class;

Spring IOC反射机制

  1. 找到并加装配置
  2. 解析配置文件中的bean元素,并识别id和class
  3. 通过反射(Class.forName().newInstance())创建这个bean的实例
  4. 将id作为key、实例作为value存放进Spring容器中
  5. getBean取出实例

Henry
38 声望8 粉丝