Java 类加载
本文将介绍 Java 类的加载、连接与初始化。
一、类的加载、连接与初始化
1. 何时进行类的加载、连接与初始化?
- 当程序需要使用某个类时
- 当使用预加载机制时
2. 类的加载
类加载是指将类的 class 文件读入内存,并为之创建一个 Java.lang.Class
对象。
Java 中的所有类其实也是实例,它们是
Java.lang.Class
类的实例。
3. 类的连接
连接阶段负责将类的二进制数据合并到 JRE 中,可以分为以下三个阶段:
- 验证阶段:校验被加载的类是否有正确的内部结构,并与其它类协调一致
- 准备阶段:为类的类变量分配内存,并置零
- 解析阶段:将类的二进制数据中的符号引用替换为直接引用
4. 类的初始化
可以分为以下几个步骤:
假如类的直接父类还没有初始化,加载、连接并初始化该直接父类
对类进行初始化,主要就是对类变量进行初始化
为类变量指定初始化值的方法:
- 在声明类变量时指定初始值
- 使用静态初始化块为类变量指定初始化值
二、类加载器
1. 什么是类加载器?
类加载器负责将 .class
文件加载到内存中,并生成对应的 Java.lang.Class
对象。
2. 类加载机制
(1) 类的唯一标识
当类已经被加载之后,就不应当再次载入。正如一个对象有一个唯一的标识一样,一个载入 JVM 的类也有唯一的标识
在 Java 中,类用全限定类名作为标识,在 JVM 中,类用全限定类名及其类加载器作为标识。
这意味着,一个类可以被多个类加载器加载,它们会被视为不同的类。
(2) 类加载机制
- 全盘负责:当一个类加载器负责加载某个 Class 时,该 Class 所依赖的和引用的其它 Class 也将由该加载器负责载入,除非显性使用另外的类加载器来载入
- 父类委托:先让父类加载器试图加载,只有在父类加载器无法加载时,才尝试从自己的类路径加载该 Class
- 缓存机制:保证所有加载过的 Class 都会被缓存,当程序中需要使用某个 Class 时,先从缓存区中搜寻该 Class,只有当缓存区中不存在该 Class 时,才会进行加载
3. 内置类加载器
Java 运行时具有以下内置类加载器:
Bootstrap ClassLoader:根类加载器,负责加载 Java 核心类
Java 核心类:包以 Java 开头
Extension ClassLoader:扩展类加载器,负责加载 Java 扩展类
Java 扩展类:包以 Javax 开头
App ClassLoader:系统类加载器,又被称为应用程序类加载器,负责加载用户路径上所指定的类库
参考
疯狂 Java 讲义