Java ClassLoader 中双亲委派机制
2018-02-09 本文已影响970人
一半晴天
在学习 Java 虚拟机时 看到一个新名词: 双亲委派
在此记录一下自己的疑问与理解。
- 什么双亲?
- 为什么需要双亲委派?
什么是双亲委派机制
双亲委派机制 主要体现在ClassLoader#loadClass
如下代码中:
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
return c;
}
上面代码逻辑简单易懂, 主要是以下4个步骤:
-
findLoadedClass(name)
从已加载的类的缓存中查找。 -
parent.loadClass(name, false)
如果父加载器不为空,则委托父加载器加载`。 -
findBootstrapClassOrNull(name)
委托 bootstrap 加载器加载。 -
findClass(name)
最后调用findClass(name)
加载。
这个双亲体现在上面的步骤 2) 和 3) 也就是下面的几行代码:
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
第一个亲就体现在 parent
即父加载器。
第二个新就体现在 bootstrap 加载器。因为 bootstrap 加载器是 JVM 中的根加载器。
为什么需要双亲委托机制
简单来说,这是为了保证 JDK 核心类库都是由 bootstrap 加载器加载。
那为什么需要保证 JDK 核心类库由 bootstrap 加载器加载呢?其实这主要是为了保证 JDK 核心类库都是由同一个加载器加载?那为什么要保证 JDK 核心类库都需要由同一个加载器加载呢?这是为了保证核心类库的类在 JVM 中只有一个对应实体。也就是为了保证类型关系的正确性。