文章目录
Java中的类加载机制
- 说一说类加载的过程?
- 说一说双亲委派机制?
- 为什么说JDBC驱动加载打破了双亲委派机制?
- 参考
类加载过程
系统加载class文件主要有3个步骤:
加载 ==> 连接 ==> 初始化
其中连接又分为:
验证 == > 准备 ==> 解析
-
加载:
- 通过全类名获取此类的二进制字节流
- 将字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在内存中生生一个代表此类的Class对象, 作为方法区这些数据的访问入口
注: 加载阶段和连接阶段的部分内容是交叉进行的, 加载阶段尚未结束, 连接阶段可能就已经开始了.
-
验证:
-
准备:
-
准备阶段是为静态变量, 常量设置初始值
// 常量会直接赋值 private final int AGE = 18; // 静态变量会赋予默认的零值(0, null, false等) public static Straing value = 10;
-
-
解析:
- 解析的阶段就是虚拟机将常量池的中的符号引用装换为直接引用的过程
- 符号引用就是一组符号来描述目标, 直接引用就是直接指向目标的指针或间接定位到目标的句柄
-
初始化:
-
初始化是真正执行类中定义的Java程序代码(字节码), 只有主动使用类才会初始化类:
虚拟机规范了有且只有5种情况, 必须对类进行初始化:
- 当遇到 new, getstatic, putstatic, 或 invokestatic这4条直接码指令时, 比如new一个类的对象, 读取, 调用一个类的静态字段;
- 使用反射Class.forName(“类全限名”)获取一个类的Class对象, 如果类没初始化, 会触发其初始化;
- 初始化一个类, 如果父类还未初始化, 则先触发父类初始化;
- 虚拟机启动时, 用户需要定义一个要执行的主类(包含main()方法的类), 虚拟机会先初始化这个类;
- MethodHandle和VarHandle可以看作是轻量级的反射调用机制,而要想使用这2个调用, 就必须先使用findStaticVarHandle来初始化要调用的类。
- (补充)当一个接口中定义了JDK8新加入的默认方法(被default关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化。
-