Java-双亲委派机制

双亲委派机制

    • 什么是双亲委派机制
    • 类加载器的类别
      • BootstrapClassLoader
      • ExtClassLoader
      • AppClassLoader
    • 为什么要这么设计呢?

什么是双亲委派机制

      Java 是运行在 Java 的虚拟机(JVM)中的,但是它是如何运行在 JVM 中了呢?Java 将源代码通过编译器编译成 .class 的字节码文件,然后交由 ClassLoader 负责将这些 .class 文件给加载到 JVM 中去执行。ClassLoader 加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,每一个层级类加载器都是如此,如果上级的类加载器没有加载,子类加载器才会去尝试加载这个类。
      下面我们通过 Java 的 ClassLoader 抽象类的代码片段来证明上述所说:

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{
     
     synchronized (getClassLoadingLock(name)) {
     
         // 首先,检查是否已经被类加载器加载过
         Class<?> c = findLoadedClass(name);
         if (c == null) {
     
             long t0 = System.nanoTime();
             try {
     
                 if (parent != null) {
     // 存在父加载器,递归的交由父加载器
                     c = parent.loadClass(name, false);
                 } else {
     // 不存在父加载器,则递归给顶层Bootstrap类加载器
                     c = findBootstrapClassOrNull(name);
                 }
             } catch (ClassNotFoundException e) {
     
                 // ClassNotFoundException thrown if class not found
                 // from the non-null parent class loader
             }

             if (c == null) {
     
                 // 如果bootstrapClassLoader 仍然没有加载过,则递归回来,尝试自己去加载class
                 long t1 = System.nanoTime();
                 c = findClass(name);

                 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                 sun.misc.PerfCounter.getFindClasses().increment();
             }
         }
         if (resolve) {
     
             resolveClass(c);
         }
         return c;
     }
}

通过这段代码解释了双亲委派运行机制,为了更好的补充说明,下面通过一张流程图来展示:
Java-双亲委派机制_第1张图片

类加载器的类别

BootstrapClassLoader

      BootstrapClassLoader(启动类加载器),由 c++ 编写,加载 java 核心库 java.*,构造 ExtClassLoader 和 AppClassLoader。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。

ExtClassLoader

      ExtClassLoader (标准扩展类加载器),java 编写,主要加载JAVA_HOME/lib/ext 目录中的类库,开发者可以直接使用标准扩展类加载器。

AppClassLoader

      AppClassLoader(系统类加载器),java编写,加载用户路径 Classpath 路径下的类包。

为什么要这么设计呢?

  1. 安全机制:保证核心 .class 不能被篡改。通过委托方式,不会去篡改核心 .class,即使篡改也不会去加载,即使加载也不会是同一个 .class 对象了。不同的加载器加载同一个 .class 也不是同一个 Class 对象。这样保证了 Class 执行安全。
  2. 避免重复加载:当父加载器已经加载了该类,子类加载器就不会再加载,保证数据安全。

你可能感兴趣的:(Java进阶知识)