cocobear9  
一枚普通的zisuer(lll¬ω¬),努力每天多学一点点

从什么是类开始说起…

我们都知道类也是由成员变量`构造器和方法等构成的

所以其本质也是一个一个的对象 需要通过对象来描述和创建

这里的对象是什么呢? 是Class类的对象class<?>

因为class<?>描述的是类的结构 所以一个特定的class<?>对应一个普通类的所有对象(这里有点绕)

Class类对象无法直接创建 因为它的构造方法是私有的 是由JVM随类装载时自动创建

经常说的
class<?> clazz = Class.forName("com.test.model.Student");

就是一个根据完整类名加载类对象(有别于"类的对象"!)的过程

而平时更多接触的

Student stu = new Student();
  • 1

就是根据上面的clazz为模板创建的 等同于

Student stu = clazz.newInstance();
  • 1

class<?>表示接收的类对象可以是任意类型的
与之相对应的比如class<String>就只能接收String的类对象 以此类推

说到这里 似乎一切都开始变得清晰了 但还有一个重要的问题:

clazz存放在哪里\?

不知道你在debug你的bug的时候有没有注意到一个总会出现但又极不起眼的地方:
IDEA中的普通程序

这是什么?

Class我知道了是Class类 后面加@数字是什么意思?

其实不只是Class
任何类(在其作用域范围内)为了表示一个唯一的对象都需要加一个数字 也就是该对象的HashCode

再深入一点
show objects
通过show objects可以看到程序里(或断点之前)加载到的所有类对象都在这里
(我怀疑数字的大小也反映了类的加载顺序 没有深入了解过 有研究过的同学请告知我)

每个类对象又都是生产其对应类的对象的模板

就连类的加载和对象的建立都是发散性的

我觉得这也是面向对象思想这座金字塔的精髓所在

最后经过以上的分析 我们不难推测出JVM创建对象的过程:

在需要创建对象时 JVM会检查该类是否已被加载

如果没有 JVM就会通过类加载器(ClassLoader)根据类的名称去找对应的.class文件(这也是Java程序运行前需要先编译的原因 除了加载.class ClassLoader同样负责加载文件和配置等其他资源)

这时如果没有发生错误 此类的类对象(Class对象)会被加载到内存 就像市长得到了他的专属印章(类模板)

然后市长(JVM)就可以在你(程序员)的授意下啪啪啪地在各种文件上盖上"同意"(创建类的对象) 愉快地造各种各样(对象多样性)的违规建筑(bug)了

最后的总结:

.java – 编译 --> .class – 类加载器 --> Class类对象class --> 实例化 --> 实例对象

普通类是对普通对象的抽象;
类对象是对普通类的抽象;
类对象是JVM的造人工具;
反射就是造人.avi的重放.
聪明的你明白了吗?[/doge]

转:https://blog.csdn.net/zzy372219506/article/details/90934987?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

posted on 2020-08-25 19:34  cocobear9  阅读(887)  评论(0编辑  收藏  举报