美文网首页
类加载 - 被谁加载

类加载 - 被谁加载

作者: 武曌思 | 来源:发表于2019-08-03 14:17 被阅读0次

类加载包含两部分:一部分是被谁加载,另一部分是如何加载。
被谁加载是指 ClassLoader 的双亲委派模型,如何加载是指类的加载过程。
这篇博客介绍双亲委派模型,特别感谢 @书呆子Rico老师 的博客


ClassLoader 结构核心思想

class ClassLoader {
    /**
     * 父加载器
     */
    ClassLoader parent;
    /**
     * 已经加载的 class
     * 这个属性是我假想的,为了配合 {@link #findLoadedClass} 的猜想
     */
    Map<String, Class> loadedClasses;

    /**
     * 尝试从已经加载的类中寻找,如果没有返回 null
     * 真实的实现是 native 方法,我猜想是存了一个类名到类实例的映射,如下
     */
    Class<?> findLoadedClass(String name){
        return loadedClasses.get(name);
    }

    /**
     * 当前类加载器尝试去加载一个类,内部实现就是类的加载过程
     * 为什么说尝试?因为当前类加载器可能无法加载这个类,会返回 null
     */
    Class<?> findClass(String name){}

    /**
     * 双亲委派模型的实现,也是类加载的直接入口
     */
    Class<?> loadClass(String name){}
}

双亲委派模型

当类加载器尝试加载一个类时,会首先查看自己加载过的类。如果没有查找到,不是马上去加载,而是去询问父加载器(这是一个递归的过程)。如果父加载器也没有加载,自己才会加载。双亲委派模型是通过组合的方式实现的,不是继承

双亲委派模型图

双亲委派实现自己实现的伪代码

Class<?> loadClass(String name) {
    // 查找自己加载过的类
    Class<?> loadedClass = findLoadedClass(name);
    if (loadedClass == null) {
        // 尝试让父类加载
        if (parent == null) {
            // 调用 BootstrapClassLoader 去加载,后面介绍 Java 类加载器的层级结构
        } else {
            loadedClass = parent.loadClass(name);
        }
        // 如果父类没有加载,自己加载
        if (loadedClass == null) {
            loadedClass = findClass(name);
        }
    }
    // 返回最终结果,此时还有可能为 null
    // 如果当前类加载器有子加载器,则子加载器还会尝试加载,否则就会包 ClassNotFoundException
    return loadedClass;
}

双亲委派作用

  • 防止类重复加载提高效率
  • 保证核心类安全,无法被替换
    假设通过网络传递一个名为java.lang.Integer的类,通过双亲委托模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字的类,发现该类已被加载,并不会重新加载网络传递的过来的类,而直接返回已加载过的Integer.class,这样便可以防止核心API库被随意篡改。

Java 类加载器层级结构

如双亲委派模型图中展示的,Java 中现有类加载器分三层。

  • BootstrapClassLoader,启动类加载器,顶级类加载器,由 native 实现,加载JAVA_HOME/lib下面的核心类库或-Xbootclasspath选项指定的jar包等虚拟机识别的类
  • ExtClassLoader,拓展类加载器,父加载器是BootstrapClassLoader,所以parent==null,加载JAVA_HOME /lib/ext或者由系统变量-Djava.ext.dir指定位置中的类
  • AppClassLoader,系统类加载器,默认的类加载器,也是自定义类加载器的父加载器,加载当前类所在路径及其引用的第三方类。

相关文章

  • 类加载 - 被谁加载

    类加载包含两部分:一部分是被谁加载,另一部分是如何加载。被谁加载是指 ClassLoader 的双亲委派模型,如何...

  • java基础知识之java类加载器

    1. 什么是类加载器 类加载器就是用来加载类的东西!类加载器也是一个类:ClassLoader 类加载器可以被加载...

  • java类加载机制、类加载器、自定义类加载器

    java类加载机制、类加载器、自定义类加载器 类加载机制 java类从被加载到JVM到卸载出JVM,整个生命周期包...

  • Java类加载机制

    引言 介绍一下java类加载的过程 类加载的时机 类从被加载到java虚拟机内存中开始,被分为7个阶段,包括加载,...

  • ClassLoader

    1. 类的加载、连接、初始化 加载:查找并加载类的二进制数据 连接:-- 验证: 确保被加载类的正确性-- 准备:...

  • 第一章 类加载过程

    要点 类加载过程 类加载器 一、类加载过程 1.类的加载过程 类的加载 .class文件过程分为:加载---->连...

  • 深入理解jvm类加载机制

    1.什么是类加载? 类加载机制一个很大的体系,包括类加载的时机,类加载器,类加载时机。 1.1类加载过程 加载器加...

  • 类加载机制

    JVM类加载机制 类加载子系统 类加载过程 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:...

  • class(三)ClassLoader类加载机制

    字节码文件是如何被加载的?以及加载时机 java中的已有的类加载器 双亲委派机制 通过自定义类加载器加载磁盘的字节...

  • JVM类加载入门

    一 类加载顺序 class类加载-->验证-->准备--->解析--->初始化 class类加载:通过类加载器加载...

网友评论

      本文标题:类加载 - 被谁加载

      本文链接:https://www.haomeiwen.com/subject/tdtjdctx.html