1.缘由何起
看到一个问题,问题是
类加载机制,一个类加载到虚拟机中一共有几个步骤,这些步骤的顺序哪些是固定的,哪些是不固定的,为什么不固定?
这个问题看得我有点懵,难道类加载的步骤顺序还是根据某些条件的变化而改动的?之前看周志明大神的JVM书籍时好像并没有印象啊?
看来确实有遗漏,补习一下相关知识。
2.JVM类加载基础知识
在看到这个问题时,其实对类加载的步骤已经有些遗忘了,自己再简单的记录一遍,顺便帮读者们温习一下。
加载:根据类路径将硬盘上的.class文件加载进内存,加载时用到了双亲委派机制。
校验:JVM作为成熟的商用虚拟机标准,肯定要对各种输入进行仔细的检查和校验,防止hacker攻击。
准备:为类中的static字段和static final字段开辟空间,将类中的static字段赋默认值,为static final字段赋初始化值。
解析:将有变量、方法等元素的 符号引用 指向 直接引用 。
初始化:将static字段赋初始化值以及相应的类初始化工作。
使用:在程序中使用Class对象。
卸载:当不再以任何形式引用到该类对象及其变量,并且相应的ClassLoader也已经被卸载,这个时候该类可被卸载。
3.静态绑定和动态绑定
程序中绑定的概念:将一个字段或者方法调用与实际的类关联起来。
白话解释:我在使用一个变量或者方法时,需要知道方法或者变量属于哪个类,将方法和变量与对应的类进行关联的过程,称之为绑定。
静态绑定指的是在代码的编译期就已经能够获取到关联的类信息;
动态绑定指的是编译期获取不到,只有程序运行期才能知晓关联的类信息;
3.1 动态绑定 - @Override
解释到这里,动态绑定最常见的场景想必大家都已经想到了,就是重写和实现。在编译期时,存在父类子类方法的重写&接口和实现类对接口方法的实现的相关情况,仅凭静态的代码符号并不能确定关联的类。只有在运行期,JVM能够获取到运行的上下文,才能推断出到底哪个类才是最终要绑定的类,才能获取到最终的直接引用,而确定直接引用的步骤,称之为——解析。
3.2 静态绑定 - static construct final private
相比于动态绑定,静态绑定是在编译器就可以确定关联类信息的,比如private方法,只有该类的实例对象才能调用,不会出现实现或者重写等行为,所以private方法的解析,在准备步骤后就会执行。construct method,final method,static method同理。
4.结论
解析这步骤的顺序是不确定的,当存在动态绑定情况时,解析出现在程序的运行期,而静态绑定相关的解析存在程序的编译期。
所以类加载完整的顺序为
1.加载
2.校验
3.准备
4.静态解析(如有必要)
5.初始化
6.使用
7.动态解析(如有必要)
8.卸载
网友评论