您的位置:首页 > 其它

JVM(五) 类的连接

2017-05-08 15:52 148 查看

what

类被加载后,就进入连接阶段。连接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去。

连接:

*验证:确保被记载的类的正确性

*准备:为类的静态变量分配内存,并将其初始化为默认值

*解析:把类中的符号引用转换为直接引用

类的验证

内容

1、类文件的结构检查

确保类文件遵从Java类文件的固定格式

2、语义检查

确保类本身符合Java语言的语法规定,比如验证final类型的类没有子类,以及final类型的方法没有被覆盖。

3、字节码验证

确保字节码流可以被Java虚拟机安全地执行。字节码流代表Java方法(包括静态方法和实例方法),它是由被称做操作码的单字节指令组成的序列,每一个操作码后都跟着一个或多个操作数。字节码验证步骤会检查每个操作码是否合法,即是否有着合法的操作数。

4、二进制兼容性的验证

确保相互应用的类之间协调一致。例如在Work类的gotoWork()方法中会调用Car类的run()方法。Java虚拟机在验证Worker类时,会检查在方法区内是否存在Car类的run方法,假如不存在(当Worker类和Car类的版本不兼容,就会出现这种问题),就会抛出NoSuchMethodError错误。

很多的验证都是出于安全性的考虑,因为它要防止一些恶意用户来手动地构造class文件,如果不符合jdk规范的话,就有可能侵入并破坏你的系统。采取这么多的验证机制就是很大程度上为了确保安全性。

类的准备

在准备阶段,Java虚拟机为类的静态变量分配内存,并设置默认的初始值。例如对于以下Sample类,在准备阶段,将为int类型的静态变量a分配4个字节的内存空间,并且赋予默认值0,为long类型的静态变量b分配8个字节的内存空间,并且赋予默认值0。

public class Sample{
private static int a =1;
public static long b;

static{
b=2;
}
...
}以上程序在准备阶段,a和b都为默认值0,直到初始化阶段才显示赋值为1,2.

类的解析

        在解析阶段,Java虚拟机会把类的二进制数据中的符号引用替换为直接引用。例如在Worker类的gotoWork()方法中会引用Car类的run()方法。

public void gotoWork(){
car.run(); //这段代码在Worker类的二进制数据中表示为符号引用
}       在Worker类的二进制数据中,包含了一个对Car类的run()方法的符号引用,它由run()方法的全名和相关描述符组成。在解析阶段,Java虚拟机会把这个符号引用替换为一个指针,该指针指向 Car类的run()方法在方法区内的内存位置,这个指针就是直接引用。



     
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息