仓库源文站点原文


layout: post title: "分析new和反射机制创建对象的区别" categories: Java tags: 反射机制

author: 张乘辉

  1. 所有的类都是在第一次使用时,被动态加载到jvm内存中,即首次创建对象时,或者类中的静态方法首次被调用时,或者静态属性被访问时,类加载器定位找到对应的class文件;
  2. 类加载器把class文件载入内存,并生成class对象,把对象中所有的静态资源都执行一遍,并把这些静态资源存放到jvm的方法区中,有且只在class对象首次生成时执行一次;
  3. new创建对象时,首先检查该类的class文件是否已加载到jvm内存中并生成class对象,若有,则会在jvm堆内存中为该类分配足够的空间;
  4. 把存储的空间清空,并把该类的所有的基本数据类型设置成默认值,对象引用设置null;
  5. 继续执行字段中被自定义的值的一些初始化操作;
  6. 调用构造方法,便创建了一个对象。

与反射机制创建对象的区别

  1. new的对象在编译环境中要必须在类路径中有,class.forName()在编译时可以不在类路径中,所以class.forName()指定了ClassLoader后,就可以在指定的环境中查找某些类,即:new一个对象允许class文件还没加载进来,jvm虚拟机会自动检查内存中是否有这个class对象,若没有就通过类加载器加载进来,而newInstance()必须要确保class文件已经加载进内存中才能产生一个对象,这时需通过class.foName()方法加载class文件。
  2. newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。

总结

  1. 所以如果没有反射机制,每次增加类时,都需要把类的class文件放在类路径中,再修改源代码new这个类产生对应类的对象;
  2. 有了反射机制后,只需要在配置文件写上相应的类名称,再通过io流读取配置文件中的类名,即可通过class.forName()方法找出相应的class文件并加载进内存中,再通过newInstance()方法创建一个对象,此时的对象是一个Object类型的对象,需要转换成相对应的类类型。这样就可以在不修改源代码的情况下通过修改配置文件进行功能的更新和扩展了。