在Java中,双亲委派机制(Parent Delegation Model)是类加载器(ClassLoader)在加载类时的一种工作机制。它确保了类的加载过程是按照一定的层次结构和顺序进行的,从而保证了类的唯一性和安全性。
双亲委派机制的工作原理
-
委托机制:
- 当一个类加载器(如
AppClassLoader
)接收到加载类的请求时,它首先不会自己去尝试加载这个类,而是把这个请求委托给父类加载器(如ExtClassLoader
)去完成。 - 父类加载器在接收到请求后,同样不会直接加载类,而是继续向上委托给它的父类加载器(如
BootstrapClassLoader
)。
- 当一个类加载器(如
-
查找类:
- 如果父类加载器能够找到并加载这个类,那么加载过程就结束了。
- 如果父类加载器无法找到这个类,那么子类加载器才会尝试自己去加载这个类。
-
加载顺序:
- 类加载器按照从上到下的顺序依次尝试加载类,即
BootstrapClassLoader
->ExtClassLoader
->AppClassLoader
。
- 类加载器按照从上到下的顺序依次尝试加载类,即
类加载器的层次结构
-
Bootstrap ClassLoader:
- 最顶层的类加载器,负责加载Java的核心类库(如
rt.jar
中的类)。 - 它是由C++实现的,所以在Java代码中无法直接获取到它的引用。
- 最顶层的类加载器,负责加载Java的核心类库(如
-
Extension ClassLoader(ExtClassLoader):
- 负责加载Java的扩展类库(如
jre/lib/ext
目录下的jar包)。 - 它是
sun.misc.Launcher$ExtClassLoader
类的实例。
- 负责加载Java的扩展类库(如
-
Application ClassLoader(AppClassLoader):
- 负责加载应用程序的类路径(
CLASSPATH
)下的类。 - 它是
sun.misc.Launcher$AppClassLoader
类的实例。
- 负责加载应用程序的类路径(
双亲委派机制的优点
-
类的唯一性:
- 通过双亲委派机制,可以确保同一个类在不同的类加载器中只会被加载一次,从而避免了类的重复加载和冲突。
-
安全性:
- 由于核心类库(如
java.lang.Object
)总是由BootstrapClassLoader
加载,因此可以防止用户自定义的类覆盖核心类库中的类,从而保证了Java平台的安全性。
- 由于核心类库(如
示例
假设有一个类com.example.MyClass
,当AppClassLoader
接收到加载这个类的请求时,它会按照以下顺序进行:
AppClassLoader
将请求委托给ExtClassLoader
。ExtClassLoader
将请求委托给BootstrapClassLoader
。BootstrapClassLoader
在自己的加载路径中查找com.example.MyClass
,如果找不到,则返回null
。ExtClassLoader
在自己的加载路径中查找com.example.MyClass
,如果找不到,则返回null
。AppClassLoader
在自己的加载路径中查找com.example.MyClass
,如果找到,则加载并返回该类。
总结
双亲委派机制是Java类加载器的一种重要机制,它通过委托父类加载器先尝试加载类,确保了类的唯一性和安全性。这种机制在Java的类加载过程中起到了至关重要的作用。