一文搞懂双亲委派模型「建议收藏」

一文搞懂双亲委派模型「建议收藏」类加载器虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。从Java虚拟机的角度来讲,只存在以下两种不同的类加载器:启动类加载器(BootstrapClassLoader),使用C++实现,是虚拟机自身的一部分所有其它类的加载…

大家好,又见面了,我是你们的朋友全栈君。

类加载器

虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取此类的二进制字节流”这个动作放到 Java 虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。

从 Java 虚拟机的角度来讲,只存在以下两种不同的类加载器:

  • 启动类加载器(Bootstrap ClassLoader),使用 C++ 实现,是虚拟机自身的一部分
  • 所有其它类的加载器,使用 Java 实现,独立于虚拟机,并且全部继承自抽象类 java.lang.ClassLoader。

从 Java 开发人员的角度看,类加载器可以划分得更细致一些:

  • 启动类加载器(Bootstrap ClassLoader):前面已经大致介绍过了,这个类加载器负责将存放在 <JRE_HOME>\lib 目录中的,或者被 -Xbootclasspath 参数所指定的路径中的,并且是虚拟机识别的(仅按照文件名识别,如 rt.jar,名字不符合的类库即使放在 lib 目录中也不会被加载)类库加载到虚拟机内存中。启动类加载器无法被 Java 程序直接引用,用户在编写自定义类加载器时,如果需要把加载请求委派给启动类加载器,直接使用 null 代替即可。
  • 扩展类加载器(Extension ClassLoader):这个类加载器是由 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的。它负责将 <JAVA_HOME>/lib/ext 或者被 java.ext.dir 系统变量所指定路径中的所有类库加载到内存中,开发者可以直接使用扩展类加载器。
  • 应用程序类加载器(Application ClassLoader):这个类加载器是由 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。由于这个类加载器是 ClassLoader 中的 getSystemClassLoader() 方法的返回值,因此一般称为系统类加载器。它负责加载用户类路径(ClassPath)上所指定的类库,开发者可以直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

我们的应用程序都是由上述这三种类加载器互相配合从而实现类加载,如果有必要,还可以加入自己定义的类加载器。
 

双亲委派模型

在这里插入图片描述
上图是上面所介绍的这几种类加载器的层次关系,称为类加载器的双亲委派模型。该模型要求除了顶层的启动类加载器外,其它的类加载器都要有自己的父类加载器。

一言概之,双亲委派模型,其实就是一种类加载器的层次关系
 

1. 工作过程

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此。

因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。

在分析类加载的源码时,我们还会再一次细致的提及类加载的过程。

2. 好处

  • 使得 Java 类随着它的类加载器一起具有一种带有优先级的层次关系,从而使得基础类得到统一。 例如 java.lang.Object 存放在 rt.jar 中,如果编写另外一个 java.lang.Object 并放到 ClassPath 中,程序可以编译通过。由于双亲委派模型的存在,所以在 rt.jar 中的 Object 比在 ClassPath 中的 Object 优先级更高,这是因为 rt.jar 中的 Object 使用的是启动类加载器,而 ClassPath 中的 Object 使用的是应用程序类加载器。rt.jar 中的 Object 优先级更高,那么程序中所有的 Object 都是这个 Object。
  • 避免了多份同样字节码的加载,内存是宝贵的,没必要保存相同的两份 Class 对象,例如 System.out.println() ,实际我们需要一个 System 的 Class 对象,并且只需要一份,如果不使用委托机制,而是自己加载自己的,那么类 A 打印的时候就会加载一份 System 字节码,类 B 打印的时候又会加载一份 System 字节码。而使用委托机制就可以有效的避免这个问题。

3. 实现

双亲委派模型对于保证 Java 程序的稳定运作很重要,但它的实现却非常的简单,实现双亲委派的代码都集中在 java.lang.ClassLoader 的 loadClass() 方法中。如下所示

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { 
   
        synchronized (getClassLoadingLock(name)) { 
   
            // 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);
                }
            }
            if (resolve) { 
   
                resolveClass(c);
            }
            return c;
        }

从 loadClass() 的源码,我们再来看一下双亲委派模型的工作过程。它可以被下面这张图来概括。
在这里插入图片描述
主要可以分为两步:

  • 首先从底向上的检查类是否已经加载过,就是这行代码:Class<?> c = findLoadedClass(name);
  • 如果都没有加载过的话,那么就自顶向下的尝试加载该类。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/125001.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • jenkins教程菜鸟_Jenkins教程:在Windows平台安装Jenkins「建议收藏」

    jenkins教程菜鸟_Jenkins教程:在Windows平台安装Jenkins「建议收藏」一、什么是JenkinsJenkins是一个开源软件项目,是基于Java开发的。我们可以利用Jenkins来实现持续集成的功能。因为Jenkins是基于Java开发的,所以在安装Jenkins之前首先需要安装Java的JDK。二、安装Jenkins在Windows平台上面安装Jenkins共有两种方式,下面分别介绍这两种方式。1、使用msi安装Jenkins安装Jenkins之前首先去Jenkin…

    2022年5月14日
    64
  • 信贷风控模型搭建及核心风控模式分类

    信贷风控模型搭建及核心风控模式分类一、当前风控模式现状近年来,信用风险管理发展呈现出数据化、模型化、系统化、自动化和智能化的特点。传统的人工专家经验正逐步被模型与算法替代。因此,科技较为领先的金融服务公司会选择采用模型方式完成对借款人的自动评估与审批。目前,对于信贷审核来说主要基于的风控模式为IPC、信贷工厂、大数据三种,每一种都有自己不同的侧重点。二、最核心的风控模式分类1.IPC模式IPC模式起源于德国邮储银行,该模…

    2022年5月1日
    62
  • Java内存模型详解

    Java内存模型详解前几天,发了一篇文章,介绍了一下JVM内存结构、Java内存模型以及Java对象模型之间的区别。有很多小伙伴反馈希望可以深入的讲解下每个知识点。Java内存模型,是这三个知识点当中最晦涩难懂的一个,而且涉及到很多背景知识和相关知识。网上有很多关于Java内存模型的文章,在《深入理解Java虚拟机》和《Java并发编程的艺术》等书中也都有关于这个知识点的介绍。但是,很多人读完之后还是搞不清楚,甚…

    2022年6月3日
    33
  • 如何修改手机桌面软件名称_安卓软件如何改名字

    如何修改手机桌面软件名称_安卓软件如何改名字安卓手机怎么修改桌面上软件的名字呀!以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!安卓手机怎么修改桌面上软件的名字呀!使用360手机桌面,在图标上长按可以直接改。或者你使用apkeditor修改软件安装包求助,怎么修改桌面上软件的图标和名字如果是快捷方式的话,点击右键-》属性,在常规选项卡下修改名字,在快捷方式选项卡…

    2022年9月23日
    3
  • 科学计算机度转弧度,角度弧度换算器在线(70°角度转换弧度)

    科学计算机度转弧度,角度弧度换算器在线(70°角度转换弧度)1°=0.01745rad1rad=57.30°计算过程:1°=π/180≈0.01745rad1rad=180/π=57.30°扩展资料:数学上是用弧度而非角度,因为360的容易整除对数学不重要,而数.角度是DEG,弧度是RAD,梯度是GRA。转换模式的方法是按MODE,然后按相应的键。不同型号可能不一样求采纳!!!!!!!!!!1弧度=180/π度1度=…

    2022年6月30日
    150
  • centos7.4安装docker_centos安装python3.6

    centos7.4安装docker_centos安装python3.6前言当我们在一台电脑上搭建了python3.6的环境,下次换台电脑,又得重新搭建一次,设置环境变量等操作。好不容易安装好,一会提示pip不是内部或外部命令,一会又提示pip:commandno

    2022年7月28日
    13

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号