一.类的生命周期

1. 加载(Loading):找 Class 文件
2. 验证(Verification):验证格式、依赖
3. 准备(Preparation):静态字段、方法表
4. 解析(Resolution):符号解析为引用
5. 初始化(Initialization):构造器、静态变 量赋值、静态代码块
6. 使用(Using)
7. 卸载(Unloading)
二.类的加载时机
1. 当虚拟机启动时,初始化用户指定的主类,就是启动执行的 main 方法所在的类;
2. 当遇到用以新建目标类实例的 new 指令时,初始化 new 指令的目标类,就是 new 一 个类的时候要初始化;
3. 当遇到调用静态方法的指令时,初始化该静态方法所在的类;
4. 当遇到访问静态字段的指令时,初始化该静态字段所在的类;
5. 子类的初始化会触发父类的初始化;
6. 如果一个接口定义了 default 方法,那么直接实现或者间接实现该接口的类的初始化, 会触发该接口的初始化;
7. 使用反射 API 对某个类进行反射调用时,初始化这个类,其实跟前面一样,反射调用要 么是已经有实例了,要么是静态方法,都需要初始化;
8. 当初次调用 MethodHandle 实例时,初始化该 MethodHandle 指向的方法所在的类。 不会初始化(可能
三.不会初始化(可能会加载)的情况
1. 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。
2. 定义对象数组,不会触发该类的初始化。
3. 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不 会触发定义常量所在的类。
4. 通过类名获取 Class 对象,不会触发类的初始化,Hello.class 不会让 Hello 类初始 化。
5. 通过 Class.forName 加载指定类时,如果指定参数 initialize 为 false 时,也不会触 发类初始化,其实这个参数是告诉虚拟机,是否要对类进行初始化。 (Class.forName”jvm.Hello”)默认会加载 Hello 类。
6. 通过 ClassLoader 默认的 loadClass 方法,也不会触发初始化动作(加载了,但是 不初始化)。
四.加载器分类
1. 启动类加载器(BootstrapClassLoader)
2. 扩展类加载器(ExtClassLoader)
3. 应用类加载器(AppClassLoader)

五.加载器特点
1. 双亲委托
2. 负责依赖
3. 缓存加载
2261

被折叠的 条评论
为什么被折叠?



