类加载
类的加载是将编译完成的.class文件的二进制数据读取到内存中,放置运行时数据的方法区内,并在堆中创建一个java.lang.Class对象,用来封装和给外部提供调用接口。
类加载过程
加载
- 加载到内存
- 将这些静态数据转换成方法去的运行时数据结构
- 在堆中生成一个代表这个类的java.lang.Class对象,作为方法区类数据的访问入口
链接
将java类的二进制代码合并到JVM的运行状态之中的过程
- 验证:确保加载的类符合JVM规范,没有安全的问题
- 准备:正式为类变量(static变量)分配内存并赋初始值
- 解析:虚拟机常量池内的符号引用替换为直接引用的过程
初始化
- 调用类构造器,由编译器自动收集类变量的赋值动作和静态语句块的语句进行合并执行
- 父类未初始化,先初始化父类
- 虚拟机通过加锁,保证多线程下初始化过程是线程安全的
- 当访问一个java类的静态域(statis field)时,只有主动引用(真正申明这个域的类)才会被初始化
- 主动引用(一定发生类的初始化)
- new一个类对象
- 调用类的静态成员(除了final常量)和静态方法
- 通过反射调用这个类
- 先启动main方法所在的类,即虚拟机启动的所在类
- 会先初始化父类
- 被动引用(不会发生类的初始化)
- final定义的常量(常量在编译阶段就存入调用的常量池中)
- 通过该类型定义的数组
- 访问父类的静态域,子类不会被初始化
- 主动引用(一定发生类的初始化)