类加载
class加载验证流程
- 加载
获取类的二进制,转为方法去数据结构,在Java堆中生成对应的Java.lang.Class对象。
- 链接
- 验证(验证class文件)
- 文件格式的验证
- (1)是否以0xCAFEBABE开头。
- (2)版本号是否合理
- 元数据验证(class内基本的语法语义的检查)
- (1)继承的父类是否存在。
- (2)非final类继承了final类(不可以的)。
- (3)实现了所有抽象方法。
- 字节码验证(很复杂)
- (1)站数据类型和操作码数据参数吻合。
- (2)跳转指令指定到合理的位置。
- 符号引用验证
- (1)常量池中描述类是否存在(继承或实现的接口是否存在)。
- (2)访问的方法或字段是否存在且有足够的权限。
- 准备
- 分配内存,并为类设置初始化(方法区)。
- 验证(验证class文件)
public static int v=1。static修饰的变量在准备阶段会被设置为0,在初始化的中被设置为1。但是对于static final类型实在准备阶段就会被赋上正确的值(public static final int v=1)。
- 解析
- 符号引用替代为直接引用。
- 初始化
- 执行类构造器
- static 变量 赋值语句
- static{}语句
- 子类的调用前保证父类的被调用
- 是线程安全的。
- 执行类构造器
图
?:java.lang.NoSuchFieldError
什么是类加载器ClassLoader
它是负责类装载过程中的加载阶段。是一个抽象类,classloader的实例将读入Java字节码将类装载到jvm中。是可以定制的,满足不同的字节码流获取方式。
classlocder的重要方法:
JDK中ClassLoader默认设计模式
自底向上检查类是否已经加载,自顶向下尝试加载类。
这样顶层classloader无法访问底层classloader
解决使用:Thread.setContextClassLoader()
-上下文加载器
-是一个角色
-解决顶层classloader无法访问底层classloader的类的问题
-基本思想是在顶层classloader,传入底层classloader的实例。
实现:
下边的不是很明白:(哪个是双亲模式,哪个是破坏的)???
热替换是怎么完成的?
?:能否只用反射,仿照上面的写法,将类注入启动classloader呢?