作用:
负责把.class文件(存储的物理文件)加载在到内存中
类加载时机:
- 创建类的实例(对象)
- 调用类的类方法
- 访问类或者接口的类变量,或者为该类变量赋值
- 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
- 初始化某个类的子类
- 直接使用java.exe命令来运行某个主类
总结:用到就加载,不用就不加载
类加载过程:
当一个类被使用的时候,才会加载到内存
- 加载
- 验证(链接)
- 准备(链接)
- 解析(链接)
- 初始化
类加载过程——加载:
- 通过包名 + 类名,获取这个类,准备用流进行传输
- 将这个类加载到内存中
- 加载完毕创建一个class对象
类加载过程:链接
验证:
作用:文件中的信息是否符合虚拟机规范有没有安全隐患
准备:
作用:负责为类的类变量(被static修饰的变量)分配内存,并设置默认初始化值
解析:
作用:本类中如果用到了其他类,此时就需要找到对应的类 像String name 这个变量,String在准备的时候是使用一些符号代替的,到了解析这一步才会找到对应的String类解析并引用
类加载过程:初始化
作用:对静态变量赋值以及初始化其他资源
类加载器分类:
- Bootstrap class loader:
虚拟机的内置类加载器 ,通常表示为null ,并且没有父null - Platform class loader:
平台类加载器 ,负责加载JDK中一些特殊的模块 - System class loader:
系统类加载器 ,负责加载用户类路径上所指定的类库 - UserClassloader:
自定义类加载器
类加载器的继承关系:
- 自定义类的父加载器为System
- System的父加载器为Platform
- Platform的父加载器为Bootstrap
public class Demo01 {
public static void main(String[] args) {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println("系统类加载器" + systemClassLoader);
ClassLoader platform = systemClassLoader.getParent();
System.out.println("平台类加载器" + platform);
ClassLoader bootstrap = platform.getParent();
System.out.println("启动类加载器" + bootstrap);
}
}
双亲委派模型:
如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,再一层一层返回给子类,然后子类加载器才会尝试自己去加载,这就是双亲委派模式
ClassLoader 中的两个方法:
方法名 | 说明 |
---|
public static ClassLoader getSystemClassLoader() | 获取系统类加载器 | public InputStream getResourceAsStream(String name) | 加载某一个资源文件 |
public class Demo02 {
public static void main(String[] args) throws IOException {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
InputStream resourceAsStream = systemClassLoader.getResourceAsStream("prop.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
System.out.println(properties);
resourceAsStream.close();
}
}
|