什么是类加载器
1.类加载器负责将.class文件 (存储在硬盘中的物理文件) 加载到内存中。
类加载器
1.类加载时机:用到就加载,不用不加载
- 创建类的实例化对象时。
- 调用类的类方法(静态方法)时。
- 访问类或者接口的类变量,或者为该类变量赋值时。(类变量指静态变量)
- 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象时。
- 初始化某个类的子类。
- 直接使用java.exe命令来运行某个主类。
2.类加载过程:
- 加载:通过包名+类名获取这个类,准备用流进行传输。将这个类通过流加载到内存中,加载完毕创建一个Class对象。
- 链接:
1.验证:链接的第一步,这一阶段为了确保Class文件字节流中包含的信息符合虚拟机的要求,并且不会威胁到虚拟自身安全。
2.准备:负责为类变量(静态变量)分配内存,并初始化其值。
3.解析:将二进制数据流中的符号引用替换为直接引用。(也就是找到本类中用到其他类的实际位置) - 初始化:静态变量赋值以及初始化其他资源。
3.类加载器的分类:
- 启动类加载器:BootStarapClassLoader 虚拟机内置的类加载器。
- 平台类加载器:PlatformClassLoader 负责加载JDK中的一些特殊的模块。
- 系统类加载器:SystemClassLoader 加载用户类路径上所指定的类库。(一般自己写的类都是通过该加载器加载到内存中的)
- 自定义类加载器:UserClassLoader。(从1到4是父到子的关系)
4.类加载器的双亲委派模型:
子加载器首先会委托父加载器加载字节码文件,因此所有的加载器最终都会传递到启动类加载器,当父类加载器不能加载时会向下委派,然后子类才会尝试自己去加载。
// 获取系统加载器
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
// 获取系统加载器的父类加载器
ClassLoader classLoader1 = classLoader.getParent();
// 获取平台加载器的父加载器
ClassLoader classLoader2 = classLoader1.getParent();
System.out.println("系统类加载器" + classLoader);
System.out.println("平台类加载器" + classLoader1);
System.out.println("启动类加载器" + classLoader2);
类加载器ClassLoader的常用方法
1.public static ClassLoader getSystemClassLoader() // 获取系统类加载器。
2.public InputStream getResourceAsStream(String name) // 加载某一个资源文件。参数为资源路径。