1. 类加载的时机
- 类的生命周期
- 加载、验证、准备、解析、初始化、使用、卸载
- 其中验证、准备、解析又被称为连接
- 这是一个交叉的过程
- 如何触发类的初始化(有且只有)
- 遇到new、getstatic、putstatic、invokestatic
- 使用反射
- 初始化一个类的时候父类还没有初始化
- 虚拟机启动时,含main方法
- 啥句柄之类的,看不懂
2. 类加载的过程
- 加载
- 通过一个类的全限定名来获取定义此类的二进制字节流
- 将这个字节流所代表的静态存储结构转化为方法区运行时的数据结构
- 在内存中生成一个代表此类的Class对象,作为方法区这个类各种数据的入口
- 验证
- 文件格式验证(魔数、版本号、常量类型等)
- 元数据验证(是否有父类、父类是否允许被继承、是否实现未实现的方法或接口等)
- 字节码验证(通过数据流和控制流分析确定程序语义是合法的、符合逻辑的
- 符号引用验证(对除自身以外的类的信息的匹配))
- 准备(正式为类分配内存)
- 仅包括类变量,而不是实例变量
- 解析(将符号引用转为直接引用)
- 符号引用:一组描述所引用目标的符号,可以是任何字面量
- 直接引用:如果有了直接引用,引用的目标必定已存在在内存中
- 可能会对同一个符号引用进行多次解析,可以进行缓存
- 类或接口的解析
- 不是数组
- 是数组
- 访问权限
- 字段解析
- 类方法解析
- 接口方法解析
- 初始化(执行类构造器的
()方法 - clinit是所有类变量的赋值动作和静态语句块的集合
- 此方法不需要显示调用父类构造器
- 可能会产生阻塞
3. 类加载器
- 类与类加载器