类加载器概述
类加载器 将.class文件(存储的物理文件)加载到内存中。
类加载时机 依附于类的使用时机,用到就加载。
类加载过程 分为加载、链接(验证、准备、解析)、初始化。
加载
- 通过一个类的全限定名获取此类的二进制字节流,
- 将字节码文件通过流加载到内存中,
- 创建一个class 对象存储加载进来的字节码文件。
验证
- 检查加载内容是否符合虚拟机规范,是否存在安全隐患
准备
- 初始化类的静态变量
解析
- 将类的二进制数据流中的符号引用替换为直接引用,即如果一个类的成员修饰符时类例如 String 的话,这个修饰符先由其他直接引用符号代替,随后根据地址进行查询更变。
初始化
- 给静态变量赋值,以及其他资源的初始化
类加载器的分类
- 启动类加载器(BootstrapClassLoader):虚拟机内置的类加载器
- 平台类加载器(PlatformClassLoader):负责加载JDK中一些特殊的模块
- 系统类加载器(SystemClassLoader):负责加载用户类路径上指定的类库
双亲委派模型
当使用类加载器去加载字节码文件时,首先或逐层委托为父类,然后从父类开始执行加载,如果最顶层父类加载器因加载范围而无法加载时,会逐层向下指派。
代码示例
public class Demo {
public static void main(String[] args) {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
ClassLoader platformClassLoader = systemClassLoader.getParent();
ClassLoader bootstrapClassLoader = platformClassLoader.getParent();
System.out.println("系统类加载器" + systemClassLoader);
System.out.println("平台类加载器" + platformClassLoader);
System.out.println("启动类加载器" + bootstrapClassLoader);
}
}
类加载器
方法 | 解释 |
---|---|
public static ClassLoader getSystemClassLoader() | 获取系统类加载器 |
public InputStream getResourceAsStream(String name) | 加载某一资源文件,并返回流的形式 |
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class Demo {
public static void main(String[] args) throws IOException {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
// prop.properties 文件在 src 目录下
InputStream is = systemClassLoader.getResourceAsStream("prop.properties");
Properties prop = new Properties();
prop.load(is);
System.out.println(prop);
is.close();
}
}