new是静态编译,反射是动态编译,但并不是说反射就绝对的优势,因为增加了反射,工作量也是增加了一层。
静态编译:
相当于把所有需要的东西都在初始化的时候加载了,如果程序一大,就很有可能会跑得慢。
动态编译:
在编译的时候,需要的模块都没有编译进去,启动程序的时候,模块不会被加载而是在运行的时候,需要哪个模块就调用哪个模块,(按需加载)。
注意:上面的过程告诉我们,我们如果用new,那么我们要创建的类都是已经“写死”在.class文件里面了,我们无法控制JVM帮我们加载类的这一项工作。
但是:如果我们用反射创建类对象,我们是相当于亲自“指导”JVM,我们“按需加载”.class文件,如果内存里面没有这个类的.class文件,那么我们用Class.forName()去叫类加载器帮忙加载就行了,而不是把程序停下来,再打一段代码,再让类加载器进行加载,从而体现出了Java的“动态性”。
在JVM中会帮你做的事情有以下:
- 编译器把类的.java文件编译为一个.class的字节码文件
- 类加载器把.class文件加载进jvm的内存中,一个Class对象生成,并放入方法区中,这Class对象对于任何类都是唯一 一个。
做完这些之后,才是new字段的工作:
- 判断内存中是否已经有那个唯一的Class对象
- 如果没有,则进行上述操作。
- 如果有,则在内存中申请空间开辟,即根据Class对象获取有关的构造器进行实例化