学习完类加载之加载篇后,让咱们继续来看加载之链接,链接分为三个步骤:验证、准备和解析三步,咱们将一一分析之。java
链接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去。安全
类加载完毕以后进入到链接阶段,链接就是将已读入到内存的类的二进制数据合并到虚拟机的运行时环境中去!在链接以前,全部的class文件都是单个的文件,之间没有任何联系,只有JVM把他们链接起来,才能将他们之间的关系有机的结合起来!eclipse
1、验证学习
验证这里可能你们会疑问了?咱们的类不是经过JVM编译成的字节码的吗,为何这里还要验证加载类的正确性,难道经过Java虚拟机的javac编译器生成的字节码还会有错误不成?固然,javac编译出来的类都是正确的,可是若是是经过其余途径生成的字节码呢?是否是正确的呢?就好比你本身建一个文本文件,而后重命名该文件为Test.class,而后让JVM来运行这个类,显然是错误的。固然由于JDK的源码是开放的,因此JVM字节码的生成规则也是公开的,因此也有一些第三方的软件能够生成符合JVM规范的字节码文件,如CGlib。spa
类的验证包括一下四个方面
–类文件的结构检查
–语义检查
–字节码验证
–二进制兼容性的验证
JDK为了保证class文件的安全性,在加载完成以后又进行了一系列的验证,这些个验证不少在编译的时候已经作过了,可是咱们前面已经提到了,不少class字节码文件不是经过javac实现的,例如eclipse就是经过JTA实现的,而咱们也能够本身随便写一个.class的文件让他加载,所以为了安全期间,JVM又进行了一次校验!指针
2、准备对象
为类的静态变量分配内存,并将其初始化为默认值,这里咱们必定要看清楚是为静态变量分配内存,而不是咱们的实例变量,为何我要强调静态变量,由于实例变量是何时产生的,是生成实例的时候产生的,而咱们通常是在new一个对象的时候才对这个类进行实例化(前提是这个类已经被加载),而咱们如今尚未加载完类,因此这个时候只能对静态变量分配内存空间(静态变量是属于这个类的而不属于某个对象),这个必定要分清楚。而后为该静态变量初始化为默认值(这个你们应该不陌生,int类型是0,boolean就是false,引用类型是null等)。blog
3、解析ip
把类中的符号引用转换为直接引用内存
这里咱们解释一下符号引用和直接引用,在Java语言里面咱们说是没有指针的,可是咱们看到上图中,car调用了car类定义的run方法,而worker类中是没有car的run的,所以在运行的时候JVM把这个有一个符号和银行替换为一个指针(这里指替换为真正的由C++底层实现的指针),而咱们java里面看到的就是符号引用,实际C++执行的才是指针,咱们称之为直接引用!
参考资料:
圣思园张龙老师深刻Java虚拟机系列