类加载机制
什么时候加载?
- 实例化类;
- 访问类或接口的静态变量;
- 访问类的静态方法;
- 实例化其子类;
- 反射调用;
- 被标记为启动类;
类加载的步骤
-
加载:将字节码加载到虚拟机,在堆上生成报错该类结构的Class对象。
首先得知道要加载谁
-
连接:分验证、准备、解析三步。
验证:检查字节码是否规范。
- 类的格式
- 语法
- 字节码格式
- 兼容性
能不能加载?检查项也是层层递进,前一项是后一项的基础。
准备:给静态变量分配内存空间,并赋予默认值。
private static int a = 2;
给 a 分配 4 byte 的空间,赋予 a int 的默认值0
解析:将符号引用替换为直接引用
public void test(Object o) { o.wait(); }
将 o.wait() 的指针绑定到 Object 的 wait() 方法;现在是真调用了!
-
初始化:初始化静态变量。
执行静态变量的初始化语句。
现在 a 可以等于2了。
类的加载器
Java自带的类加载器有三种:
- 根类加载器
- 扩展类加载器
- 系统类加载器
加载规则: 父委托机制。
各个加载器语法上没有继承关系,只在逻辑关系上有父子关系,所以叫“父委托”。
1. 如果自己的命名空间有该类,则直接返回该类应用。
2. 如果没有则交给父加载器处理,向上延申至根类加载器。
3. 再从上到下尝试加载,一旦成功,将该类引用向下层层传递。
避免 JVM 核心类被自定义加载器加载,产生安全风险。