原文出处:
iceAeterna
在了解双亲委派模型之前,先了解一下类加载器的概念:
类加载器的作用就是将真实的class文件根据位置将该Java类的字节码装入内存,并生成对应的Class对象。用户可以通过继承ClassLoader和重写findClass方法来定义自己的类加载器进行加载,系统类加载器按照层次,分为:
(1).启动类加载器(Bootstrap ClassLoader):将加载 /JAVAHOME/lib以及为-Xbootclasspath所指定的目录下的类库,是核心Java API的class文件,用于启动Java虚拟机
(2).扩展类加载器(Extension ClassLoader):将加载/JAVAHOME/lib/ext以及为java.ext.dirs所指定的目录下的类库
(3).应用程序类加载器(Application/System ClassLoader):将加载ClassPath下所指定的类库,或者称为类路径加载器
1.双亲委派
类的加载将使用双亲委派的方式,注意这里的双亲关系并非通过继承来实现,而是加载器之间指定或默认的委托加载关系,可以看到在 /java/lang/ClassLoader.java中,通过ClassLoader的构造方法显式指定了其父加载器,而若没有指定父加载器,那么将 会把系统类加载器AppClassLoader作为默认的父加载器
private ClassLoader(Void unused, ClassLoader parent) { this.parent = parent; //... } protected ClassLoader() { //getSystemClassLoader() this(checkCreateClassLoader(), getSystemClassLoader()); }
加载器对类的加载调用loadClass()方法实现:
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class c = findLoadedClass(name); // 该类没有被加载 if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { // 先交由父加载器尝试加载 c = parent.loadClass(name, false); } else { // 父加载器为空,即为BootstrapClassLoader,那么查看启动类中是否有该类 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found &nbs