我们知道 Java 的原文件会被编译器编译为 .class 文件,然后通过类加载器将类信息加载至方法区中。
类加载器
启动类加载器
Bootstrap ClassLoader,它由 JVM
自己实现,负责加载 $JAVA_HOME/jre/lib
目录下的类文件。
扩展类加载器
ExtClassLoader,它由 sun.misc.Launcher$ExtClassLoader
实现,负责加载 $JAVA_HOME/jre/lib/ext
目录下的类文件。
应用类加载器
AppClassLoader,它由 sun.misc.Launcher$AppClassLoader
实现,负责加载当前应用 classpath
下的类文件。其父类加载器为 ExtClassLoader
扩展类加载器。
自定义类加载器
用户可以通过继承 ClassLoader
抽象类实现自定义类加载器的需求。例如需要加载自定义目录中的类或者通过网络获取的类二进制流,也可以在类加载前进行加解密操作。其父类加载器为 AppClassLoader
应用类加载器。
双亲委派模型
当一个类加载器接收到类加载请求时,首先会请求其父类加载器加载,每一层都是如此,当父类加载器无法找到这个类时(根据类的全限定名称),子类加载器才会尝试自己去加载。也就是说具有相同全限定名称的两个类只会被同一个类加载器加载一次,后加载的类将会被忽略,进而能够保证类在同一个类加载器中的唯一性。