Java基础知识13--Java中new和反射创建对象的区别
1.Java反射机制
Java反射机制是在运行状态中,对于任意一个类,都能够获取这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取类信息以及动态调用对象内容就称为Java语言的反射机制。
简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在Java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息。
2.Java中new和反射创建对象
2.1 Java中new创建对象
如果我们在代码中如果写了一段
A a = new A();
在JVM中会帮你做的事情有以下:
- JVM把类的.java文件编译为一个.class的字节码文件
- 类加载器把.class文件加载进jvm的内存中,一个Class对象生成,并放入方法区中,这Class对象对于任何类都是唯一一个。
做完这些之后,才是new字段的工作:
- 判断内存中是否已经有那个唯一的Class对象
- 如果没有,则进行上述操作。
- 如果有,则在内存中申请空间开辟,即根据Class对象获取有关的构造器进行实例化,在这里我们假设是一个无参数构造,那么只需要newInstance()。
2.2 Java中使用反射创建对象
这次的代码是我们最常见的反射代码
Class c = Class.forName("A的全类名");
当JVM编译到这段代码的时候,他的步骤是:
1、使用类加载,将对应.class加载入内存的方法区中,并返回Class对象。
这时候,我们可以查看这个类对象里面的构造器方法,并使用无参数构造器进行构造实例,即如下代码
Constructor constructor = c.getConstructor();
Object obj = constructor.newInstance();
用同样的图,我们可以画出来。
到这里,我们几乎可以知道无论是反射,还是New,其实都是通过类加载器对.class文件加载进内存中,创建了Class对象。‘’
Java中反射属于动态编译,而new属于静态编译。
粗俗解释:
1、静态编译相当于把所有需要的东西都在初始化的时候加载了,如果程序一大,就很有可能会跑得慢。
2、动态编译,在编译的时候,需要的模块都没有编译进去,启动程序的时候,模块不会被加载而是在运行的时候,需要哪个模块就调用哪个模块。
上面的过程告诉我们,我们如果用new,那么我们要创建的类都是已经“写死”在.class文件里面了,我们无法控制JVM帮我们加载类的这一项工作。
但是如果我们用反射创建类对象,我们是相当于亲自“指导”JVM,我们“按需加载”.class文件,如果内存里面没有这个类的.class文件,那么我们用Class.forName()去叫类加载器帮忙加载就行了,而不是把程序停下来,再打一段代码,再让类加载器进行加载,从而体现出了Java的“动态性”。
因为Spring在加载类的实例时,我们知道其实是用工厂的方式,给出一个个实例,而在工厂里面,用了单例,但是真正实例化,则是反射的newInstance来创建对象,而不是new。
那么,为什么是反射的newInstance,而不是new呢?
那么首先我们必须明白,Java里面,反射的目的是什么?
高内聚,低耦合。
进一步,反射比new的好处是什么?
反射不用知道类名,可以直接实例化类,也就是不用硬编码。
有人问了,不知道类名那怎么反射呢?
例子:
通过new,我们这么写:
A a = New A();
通过反射,我们这么写:
Class c = Class.forName(“A”);
factory = (AInterface)c.newInstance();
其中AInterface是类A的接口,如果下面这样写,你可能会理解:
String className = “A”; Class c = Class.forName(className); factory = (AInterface)c.newInstance();
进一步,如果下面写,你可能会理解:
String className = readfromXMlConfig;//从xml 配置文件中获得字符串 Class c = Class.forName(className); factory = (AInterface)c.newInstance();
上面代码就消灭了A类名称,优点:无论A类怎么变化,上述代码不变,甚至可以更换A的兄弟类B , C , D….等,只要他们继承Ainterface就可以。
参考文献:https://blog.csdn.net/qq_26558047/article/details/109745018
https://blog.csdn.net/weixin_34672875/article/details/115074666