通常情况下,Java 程序中的 .class 文件会在以下 2 种情况下被 ClassLoader 主动加载到内存中:
1、调用类构造器
2、调用类中的静态(static)变量或者静态方法
Java中ClassLoader
JVM中自带3个类加载器:
1.启动类加载器BootstrapClassLoader
BootstrapClassLoader 与其他两种 ClassLoader 不太一样。
首先,它并不是使用Java代码实现的,而是由C/C++语言编写的,它本身属于虚拟机的一部分。因此我们无法在Java代码中直接获取它的引用。如果尝试在Java层获取BootstrapClassLoader 的引用,系统会返回 null。
BootstrapClassLoader 加载系统属性“sun.boot.class.path”配置下类文件
2.扩展类加载器ExtClassLoader(JDK 1.9 之后,改名为 PlatformClassLoader)
ExtClassLoader 加载系统属性“java.ext.dirs”配置下类文件
3.系统加载器 APPClassLoader
AppClassLoader主要加载系统属性“java.class.path”配置下类文件,也就是环境变量CLASS_PATH配置的路径。因此AppClassLoader是面向用户的类加载器我们自己编写的代码以及使用的第三方 jar 包通常都是由它来加载的。
以上 3 者在 JVM 中有各自分工,但是又互相有依赖。
JVM 又是如何知道该使用哪一个类加载器去加载相应的类呢?答案就是:双亲委派模式。
双亲委派模式
所谓双亲委派模式就是,当类加载器收到加载类或资源的请求时,通常都是先委托给父类加载器加载,也就是说,只有当父类加载器找不到指定类或资源时,自身才会执行实际的类加载过程。