在正式开始写JVM之前,首先先大致了解一下类加载的过程
第一步 加载:1.通过一个类的全限定名来获取定义此类的二进制字节流
2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
3.生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
第二步 验证:验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并 不会危害虚拟机的自身安全。
第三步 准备 : 为类变量(敲黑板了啊,重点啊,类变量啊,类!变!量!)分配内存并设置类变量初始值,这里的初始化值对于非静态变量来说,根据以下表来进行赋值:
(PS:啥是类变量,笼统的讲就是static修饰的变量)
数据类型 | 初始化值 |
int | 0 |
long | 0L |
short | 0 |
char | ‘\u0000’ |
byte | 0 |
boolean | false |
float | 0.0f |
double | 0.0d |
应用类型 | null |
假设有个变量:public int value = 123;这个是实例变量,这个在准备阶段的时候是不分配内存的,也就谈不上初始化了
又来了个变量: public static int value = 123; 这个是类变量,在准备阶段是会分配内存的,并且也会初始化,但是初始值是0 而不是123!
这个时候来了个更特殊的变量:public static final int value = 123; 由于类字段的字段属性表中存在ConstantValue属性,所以 在准备阶段JVM就会根据ConstantValue的设置将value赋值为123(这个不懂,之后会咱会去 实现,不急不急)
第四步 解析:解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。(具体去翻翻博客!反正我这暂时还没。。。)
(第2,3,4步并在一起叫链接~)
第五步 初始化:这是类加载的最后一步,到了这个阶段才真正开始执行类中定义的Java程序代码(或者说是字节码),在这阶段是根据程序员通过程序制定的主观计划去初始化类变量和其他资源的。或者从另外一个角度来说就是执行类构造器<clinit>方法的过程。
《自己动手写java虚拟机》大致也是根据这个流程来的,心里大致有个数,这样写起来目的性明确点~~~
O了~