类加载器的作用就是加载.class文件,比方说new关键字
类加载器有很多个
虚拟机自带的加载器
启动类(根)加载器
平台类加载器,java9之后就替代了扩展类加载器。
注意java8及以前是叫做扩展类加载器在 Java 8 及更早版本中,用于加载位于
%JAVA_HOME%/jre/lib/ext
目录(或由java.ext.dirs
系统属性指定的目录)下的 JAR 文件,这些 JAR 文件通常包含了对 Java 核心类库的扩展功能,比如一些第三方的安全、加密相关扩展。
应用程序加载器
我们通过下面的代码来看一下各个加载器是层层递进的形式进行加载的
当我们new一个对象的时候就会发生层层递进的情况,这里面有一个很重要的东西叫做双亲委派机制
package java.lang;
public class String {
public String toString() {
return "Hello";
}
//双亲委派机制
public static void main(String[] args) {
String s = new String();
System.out.println(s.toString());
}
}
当我们运行一个类之前,实际上是一层一层的进行寻找,找到了才执行,比方说首先从AppClassLoader也就是应用加载器向上进行查找就是到达平台类加载器,到达之后先进行寻找是否存在这个类,找不到的话再向上寻找也就是bootstrap类加载器,假如说还是无法找到,这个时候就会往下寻找,与前面相反,当我们到达应用类加载器的时候,才能够找到并执行。
上面的代码就是到达bootstrap类加载器的时候就找到了String类所以就会出现报错
当我们换一种命名方式的情况下就会正常运行
package com.JvmTest.TestjVMDemo1;
public class Test {
public String toString() {
return "Hello";
}
public static void main(String[] args) {
Test s = new Test();
System.out.println(s.toString());
}
}
执行结果也是正确的。
双亲委派机制(Parent Delegation Model)是 Java 类加载器(ClassLoader)的核心工作原则,用于保证类的唯一性、安全性和稳定性。其核心逻辑可概括为:
“子加载器收到类加载请求时,优先委派给父加载器处理,只有父加载器无法完成时,子加载器才尝试自己加载。”
✅ 示例: 应用程序类加载器(AppClassLoader
)加载用户类 com.example.MyClass
时: AppClassLoader
→ 委派 → ExtClassLoader
→ 委派 → BootstrapClassLoader
若 Bootstrap
和 Ext
均无法加载,AppClassLoader
才从 classpath
加载。
Java 类加载器采用 树形层级结构,分为四层:
Bootstrap ClassLoader
(启动类加载器)加载路径:
<JAVA_HOME>/jre/lib
(如rt.jar
)特点:唯一无父类的加载器,由 C++ 实现(Java 中显示为
null
)。
Extension ClassLoader
(扩展类加载器)加载路径:
<JAVA_HOME>/jre/lib/ext
父类:
Bootstrap
(实际由Bootstrap
加载其自身)。
Application ClassLoader
(应用类加载器)加载路径:用户类路径(
classpath
)父类:
Extension ClassLoader
。
自定义类加载器
用户继承
ClassLoader
实现,默认父类为AppClassLoader
。
📌 注意: 双亲委派中的“双亲”并非继承关系,而是组合关系(子加载器持有父加载器引用)。