类的生命周期: 加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载 (动态绑定的话解析过程可以发生在初始化阶段之后)
一、加载 完成三件事
1、通过类的全限定名来获得定义此类的二进制字节流
2、将这个类字节流代表的静态存储结构转化为方法区的运行时数据结构
3、在堆中生成一个代表此类的java.lang.Class对象,作为方法去访问这些数据结构的入口
类名 => 二进制流 => 运行时数据结构 => 堆中生成java.lang.Class对象
二、校验
1、文件格式验证:基于字节流验证。
2、基于方法区存储结构验证:元数据验证、字节码验证、符号引用验证。
三、准备
1、为变量分配内存,并将其初始化为默认值。在方法区为为变量分配内存空间。
例子:
public static int value = 1; 在准备阶段后初始化为0,编译后,存放于类构造器方法中为1,
final 修饰的准备阶段过后就是1。
四、解析 把类型中的符号引用转化为直接引用
1、类、接口、字段的解析
2、类方法解析
3、接口方法解析
a:符号引用与虚拟机实现布局无关,引用的目标不一定要加载到内存中。
各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须是一致的,
因为符号引用的字面量形式明确定义在Java虚拟机规范的Class文件格式中。
b:直接引用可以是指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。
如果有了直接引用,那引用的目标必定已经在内存中存在
五、初始化
六、类加载器分类
1、 启动类加载器(Bootstrap ClassLoader):主要负责JAVA_HOME/bin目录中的所有类,或者加载由选项-Xbootclasspath指定路径下的类
2、 拓展类加载器(ExtClassLoader):主要负责加载JAVA_HOME/lib/ext目录中的所有类型,或者由参数-Xbootclasspath指定路径下的类
3、 应用程序类加载器(AppClassLoader):主要负责加载用户类路径ClassPath下的所有类型,一般为程序的默认类加载器
4、 自定义加载器:java虚拟机规范将所有继承java.lang.ClassLoader的类加载器,定义为自定义加载器