我爱编程java面试java基础

Java ClassLoader 中双亲委派机制

2018-02-09  本文已影响970人  一半晴天

在学习 Java 虚拟机时 看到一个新名词: 双亲委派
在此记录一下自己的疑问与理解。

  1. 什么双亲?
  2. 为什么需要双亲委派?

什么是双亲委派机制

双亲委派机制 主要体现在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个步骤:

  1. findLoadedClass(name) 从已加载的类的缓存中查找。
  2. parent.loadClass(name, false) 如果父加载器不为空,则委托父加载器加载`。
  3. findBootstrapClassOrNull(name) 委托 bootstrap 加载器加载。
  4. 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 中只有一个对应实体。也就是为了保证类型关系的正确性。

上一篇 下一篇

猜你喜欢

热点阅读