我爱编程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 中只有一个对应实体。也就是为了保证类型关系的正确性。

上一篇下一篇

猜你喜欢

热点阅读