很难过。逛了一圈。还是不太清晰反射和new在执行过程中的本质区别。
说上new和反射的区别。都可罗列一堆。
new是静态编译,在类进行编译的时候吧所有模块都编译到exe了。当启动这个exe的时候所有模块都加载进入内存。
反射是动态编译。编译时没有把模块编译到一起,启动程序的时候也不会加载,而是在运行时用到那个模块就调用哪个模块。
所以RTTI和反射之间真正的区别只在于,对RTTI来说,编译器在编译时打开和检查.class文件。(换句话说,我们可以用“普通”方式调用对象的所有方法。)而对于反射机制来说,.class文件在编译时是不可获取的,所以是在运行时打开和检查.class文件。
----《java编程思想》
其实我感觉,反射是很好理解的。
jvm类加载中,加载阶段的功能就是将字节码从不同的数据源转化为二进制字节流加载到内存,并生成一个代表着各类的java.lang.Class对象。这个Class对象对任意类都是唯一的,他存储了其类的所有信息。
类是程序的一部分,每次编写并且编译了一个新类,都会生成一个Class对象(更恰当地说,是被保存在一个同名的.class文件中)。 --------《java编程思想》
反射就相当于是直接获取这个对象。所以他能使用类的所有所有。
是的。我理解的反射就是这么简单。深入到了jvm层面,思路清晰,并且应该也没有错。。。
那new呢?
所有关于new一个对象的过程,都是一通火花带闪电。
我觉得非常的难受。说好的静态编译呢,说好的编译时打开calss文件呢?
然后我发现我好像进入了一个误区。
我一直在思考的是,一个类,new加载和反射加载有什么不一样
答案很明显:没什么不一样。
所以new和反射没什么不一样,这个话题就此结束。。。
nonono。
类的加载没什么不一样,最后都会生成一个Class对象
来一张《深入理解java虚拟机》的图
1和2明确说明new和反射都会触发类“初始化”(反射中的.class好像不会初始化。。。)而初始化,肯定都会生成唯一的Class对象啊
所以就jvm的类加载层面而言。new和反射没区别
下面纯纯属于个人推测,保写不保对。。。
区别在之后。就如同
public class SS{
String s = new String();
}
先说String s=new String()。
不管之前有没有加载,反正现在堆内存里肯定有一个String的Class对象,其保存了String的所有信息。
而下一步,才是new的表现:创建对象
开始串起来了。
如果不知道某个对象的确切类型,RTTI可以告诉你。但是有一个限制:这个类型在编译时必须已知,这样才能使用RTTI识别他,并利用这些信息做一些有用的事。话句话说,在编译时,编译器必须知道所有要通过RTTI来处理的类 -------《java编程思想》
new String()这一句话,就是让你知道刚刚加载的String的Class对象类型为String。之后不是还要创建对象么。在知道对象类型后,就可以创建String的对象,并且把引用,给到class SS。这就是一开始说的,静态编译把所有模块都编译到了一起。SS这个类中直接包含了String这个new出来的类。他们的耦合性极其之高。
至于反射。懂的都懂
是的,戛然而止。哈哈哈
图中截图除了我自己拍的,还有来自这两篇文章
https://www.cnblogs.com/JackPn/p/9386182.html
https://blog.csdn.net/qq_32379477/article/details/90239891