JVM类加载器
JVM 支持两种类型的类加载器,分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)。 所有派生于抽象类 ClassLoader 的类加载器都划分为自定义类加载器。
特点:
- 启动类加载器,由C++实现,没有父类。
- 拓展类加载器(ExtClassLoader),由Java语言实现,父类加载器为null
- 系统类加载器(AppClassLoader),由Java语言实现,父类加载器为ExtClassLoader
- 自定义类加载器,父类加载器肯定为AppClassLoader。
启动类加载器(引导类加载器,Bootstrap ClassLoader)
- 这个类加载使用 C/C++ 语言实现,嵌套在 JVM 内部
- 它用来加载 Java 的核心库(JAVA_HOME/jre/lib/rt.jar、resource.jar或sun.boot.class.path路径下的内容),用于提供 JVM 自身需要的类
- 并不继承自 java.lang.ClassLoader,没有父加载器
- 加载扩展类和应用程序类加载器,并指定为他们的父类加载器
- 出于安全考虑,Bootstrap 启动类加载器只加载名为 java、Javax、sun 等开头的类
扩展类加载器(Extension ClassLoader)
- Java 语言编写,由 sun.misc.Launcher$ExtClassLoader 实现
- 派生于 ClassLoader
- 父类加载器为启动类加载器
- 从 java.ext.dirs 系统属性所指定的目录中加载类库,或从 JDK 的安装目录的 jre/lib/ext 子目录(扩展目录)下加载类库。如果用户创建的 JAR 放在此目录下,也会自动由扩展类加载器加载
应用程序类加载器(也叫系统类加载器,AppClassLoader)
- Java 语言编写,由 sun.misc.Lanucher$AppClassLoader 实现
- 派生于 ClassLoader
- 父类加载器为扩展类加载器
- 它负责加载环境变量 classpath 或系统属性 java.class.path 指定路径下的类库
- 该类加载是程序中默认的类加载器,一般来说,Java 应用的类都是由它来完成加载的
- 通过 ClassLoader的getSystemClassLoader() 方法可以获取到该类加载器
public static void main(String[] args) {
//获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader); //sun.misc.Launcher$AppClassLoader@135fbaa4
//获取其上层:扩展类加载器
ClassLoader extClassLoader = systemClassLoader.getParent();
System.out.println(extClassLoader); //sun.misc.Launcher$ExtClassLoader@2503dbd3
//再获取其上层:获取不到引导类加载器
ClassLoader bootstrapClassLoader = extClassLoader.getParent();
System.out.println(bootstrapClassLoader); //null
//对于用户自定义类来说,默认使用系统类加载器进行加载,输出和systemClassLoader一样
ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
System.out.println(classLoader); //sun.misc.Launcher$AppClassLoader@135fbaa4
//String 类使用引导类加载器进行加载。Java的核心类库都使用引导类加载器进行加载,所以也获取不到
ClassLoader classLoader1 = String.class.getClassLoader();
System.out.println(classLoader1); //null
//获取BootstrapClassLoader可以加载的api的路径
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (URL url : urls) {
System.out.println(url.toExternalForm());
}
}