回答
在 JVM 中,类加载器负责将类的字节码加载到内存中,主要有三类:
- 启动类加载器(Bootstrap ClassLoader):负责加载 Java 的核心类库,它并不是 Java 类,是 JVM 的一部分,用 C++ 实现的。它通常加载存放在
<JAVA_HOME>/jre/lib
目录下的或者被-Xbootclasspath
指定的路径中的并且文件名是被虚拟机识别的文件。 - 扩展类加载器(Extension ClassLoader):由 Java 实现,是
sun.misc.Launcher$ExtClassLoader
的实例。负责加载<JAVA_HOME>\lib\ext
目录中或被java.ext.dirs
系统变量所指定的路径的类库,这些类库被视为标准核心库的扩展。 - 应用程序类加载器(Application ClassLoader):由 Java 实现,是
sun.misc.Launcher$AppClassLoader
的实例。负责加载环境变量classpath
或者系统属性java.class.path
指定路径下的类库。
还有一类用户自定义类加载器,即我们通过继承 java.lang.ClassLoader
类来自定义类加载器,以实现特殊的加载逻辑,例如动态加载类、加载不同版本的同名类等。
Java中的类加载器采用双亲委派模型,这个模型的基本原则是:
- 当一个类加载器接收到加载类的请求时,它会先委托给其父类加载器进行加载。
- 只有当父类加载器无法找到该类时,子类加载器才会尝试自己加载。
如下图:
关于双亲委派模型,请阅读面试题:什么是双亲委派模型?