类加载机制
类加载机制:将类的字节码文件所包含的数据读入内存,同时生成数据访问入口的一种特殊机制
- 类装载:类加载器(启动类BootstrapClassLoader、扩展类Extension ClassLoader、系统类System ClassLoader、自定义类Custom ClassLoader)双亲委派; 类装载完以后 方法区以及堆里面就有数据了:方法区:类信息、静态变量、常量;堆:代表被加载类的java.lang.Class对象
- 验证:确保class文件中的字节流包含的信息复合虚拟机要求,不会危害虚拟机自身安全
A:文件格式验证:验证字节流是否符合class文件格式的规范,验证通过后才能进入内存方法区进行存储
B:元数据验证:JAVA语法验证 例如:是否继承了final类
C:字节码验证:进行数据流和控制流分析,确定程序语义是合法、符合逻辑的
D:符号引用验证:常量池中描述类是否存在 - 准备:
-
为类变量(静态变量)分配内存并且设置该变量的默认初始值
-
不包含用final修饰的static,因为在编译的时候就会分配了,准备阶段会显示初始化
-
不会为实例变量(不加static)分配初始化,类变量会分配在方法区,实例变量是随着对象一起分配到堆内存的
例如:private static final int a=1; 准备阶段后 a=0; a=1的赋值是放在构造函数中
-
解析:把类中的符号引用转换为直接引用
符号引用:用一组符号来描述目标,引用的目标不一定加载到了内存中
直接引用:直接指向目标的指针、相对偏移量 -
初始化:执行构造器方法的过程
private static final int a=1; 准备阶段后 a=0; a=1的赋值是放在构造器方法中 -
使用:new对象
-
卸载:方法区中清空类信息
双亲委派
双亲委派又叫父类委托,是指子类加载器如果没有加载过该目标类,就先委托父类加载器加载该目标类,只有父类加载器找不到字节码文件的情况下才从自己的类路径查找并加载目标类
双亲委派只是java推荐的机制,并不是强制机制,我们可以继承java.lang.ClassLoader类,实现自己的类加载器,如果想保持双亲委派就应该重写findClass(name)方法,如果想打破双亲委派模型,可以重写loadClass(name)方法
打破双亲委派的方法:
- SPI: 在META