07 类加载机制

Wu Jun 2020-02-24 14:04:19
05 Java > 01 Java 虚拟机

1 类加载时机

1.1 生命周期

类从被虚拟机加载到内存,到卸载出内存为止,类的整个生命周期:加载、连接(验证、准备、解析)、初始化、使用和卸载;

image

1.2 加载时机

虚拟机规范没有强制约束类加载的时机,但严格规定了有且只有 5 种情况必须立即对类进行初始化

2 类加载过程

加载、连接(验证、准备、解析)、初始化

2.1 加载

  1. 通过一个类的全限定名来获取定义此类的二进制流
  2. 将这个字节流转化为方法区的运行时数据结构
  3. 在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口

2.2 验证

确保 Class 文件的字节流信息符合虚拟机的要求,并且不会危害虚拟机安全;

2.3 准备

类变量(static)分配内存并设置零值,如 static final 则是直接赋值;

2.4 解析

将常量池内的符号引用替换为直接引用,可对解析结果进行缓存

2.5 初始化

执行类构造器方法 ():由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生

初始化顺序

先初始化静态成员,然后从父类到子类中,依次初始化非静态对象和构造器。

  1. 父类静态初始化块
  2. 子类静态初始化块
  3. 父类初始化块
  4. 父类构造器
  5. 子类初始化块
  6. 子类构造器

3 类加载器

3.1 类与类加载器

3.2 双亲委派模型

双亲委派模型要求除了顶层的启动类加载器外,其他的类加载器都应当有自己的父类加载器。

image

三种系统提供的类加载器:启动类加载器、扩展类加载器、应用程序类加载器;

1)工作过程

如果一个类加载器收到了类加载的请求,首先把这个请求委派给父类加载器去完成,只有父类加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载

2)好处

Java 类随着它的类加载器具备了一种带有优先级的层次关系,对保证 Java 程序的稳定运作很重要;

3)实现

实现双亲委派的代码都集中在 java.lang.ClassLoader 的 loadClass 方法中,逻辑清晰易懂

3.3 破坏双亲委派模型

双亲委派模型是 Java 设计者推荐给开发者的类加载器实现方法,但不是一个强制性的约束模型;

典型的两种情况:

3.4 自定义类加载器

除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承自java.lang.ClassLoader

自定义自己的类加载器,需要继承 ClassLoader,然后重写 loadClass() 即可。