关于类加载,网上的答案五花八门,有些语言比较官方,晦涩难懂。现在我自我总结如下:
1 加载。
把class文件读入虚拟机,转换成为运行时数据结构,也就是InstanceClass,InstanceClass是C++实现的JVM中表示一个java Class的,同时java class文件中的每个方法也会转换为C++的Method对象
记住,C++也是面向对象的,它也有类和对象的概念
还有一件事就是把元信息保存到方法区里,也就是诸如方法的字节码指令
2 验证。检查下class的格式,防止破坏JVM。这个网上的概念实在太多了。
3 准备,简单理解就是给static成员分配空间,以及赋值,注意是零值。比如int是0,long是0L。
4 解析。符号引用替换为直接引用。就是说我要执行一个方法,字节码一般都是这么个格式的invokevirtual #
7。其中
#
7是常量表的第七个常量。但是这个常量只是一个字面量,实际代码要能够找到它要执行的方法的地址,解析就是干这个的
5 初始化。这个步骤才是执行我们自己写的代码的阶段了。如果一个类里有static成员或者static代码块,编译器变出来的class文件会自动多出来一个clinit方法,也就是说对于static成员的赋值是在这里做的。
初始化:在准备阶段已经对类变量进行初始化了,这里的初始化是执行类构造器<clinit>。<clinit>()方法是编译器自动收集类中所有类变量的赋值动作和静态代码块而产生的方法(无论类变量和静态代码块的位置是什么样,都是先执行类变量的赋值动作,再执行静态代码块) 这里特别需要注意的是,初始化只是执行clinit而不是init,加载class并不是创建一个对象