百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

大厂面试系列-面试中被问到双亲委派机制是什么

toyiye 2024-06-21 12:37 11 浏览 0 评论

关于双亲委派机制,是在面试过程中会被经常问到的问题,在JVM加载类文件的过程中,需要通过类加载器进行加载,在Java中提供了很多类加载器,可以更具不同的文件进行不同的类加载。下面我们就来一起聊聊关于类加载器与双亲委派机制。

类加载器

在Java中提供了如下的四种类加载器。

  • Bootstrap ClassLoader 启动类加载器
  • Extention ClassLoader 标准扩展类加载器
  • Application ClassLoader 应用类加载器
  • Custom ClassLoader 自定义类加载器。

如图所示,一般来讲可以认为下层的类加载器继承了上层的类加载器,也就是说除了Bootstrap ClassLoader类加载器之外,其他所有的类加载器都有自己对应的父类。

双亲委派机制

所谓的双亲委派机制,其实就是指:当一个类加载器进行类加载操作的时候,他们不会直接对指定的类进行加载,而是将这个加载类的请求委托给了自己的父类去加载,当父类无法加载这个类的时候,才会将这个类指派给当前类加载器进行加载。按照这个意思可以形象的将双亲委派机制,看做一个“妈宝男”机制,什么时候都将自己的事情交给双亲来做。

根据上面的分析,我们知道了只有在父类无法加载的情况下才会有当前的类加载器进行加载操作,那么什么时候才是父类加载器无法加载呢?

对于上面提到的四种类加载器来讲,它们各自有着各自的职责。

  • Bootstrap ClassLoader:其主要的职责就是加载Java的核心类库;例如rt.jar,resource.jar等等
  • Extention ClassLoader:其主要职责就是加载核心类库的扩展类;例如在lib/ext路径下的相关Jar的加载。
  • Application ClassLoader:其主要职责就是加载对应Java应用下的所有的Class文件
  • Custom ClassLoader:主要是用户自定义的一些类加载器,可以加载一些用户指定的Class文件。

为什么要使用双亲委派机制?

说完了双亲委派机制,那么为什么Java语言要使用双亲委派机制呢?首先来讲,Java语言是一种面向对象的编程语言,也就是在我们之前介绍的时候提到的一切皆对象。而在Java语言中,离不开面向对象的三大特征。继承、封装、多态。其中继承操作我们之前提到过它是对于父类操作的扩展。也就是说在对象创建的过程中,如果没有父类对象,子类对象其实是不存在的。

也是由于这种关系,在Java的类加载其中就根据层级,以及所处的运行环境的位置来定义了四种类加载器。

首先在JVM运行的时候,需要去将底层的运行环境搭建起来,也就是在rt.jar包中会存在一些支持基础运行环境搭建的类。需要通过Bootstrap ClassLoader来进行加载,并且对于基础支持操作来讲,所有的JVM运行环境的搭建都是离不开这些基础支持的。

例如用户要去加载一个自定义的类,而这个类在我们的概念理解中它是要支持应用运行的,所以说会被一直委托到BootstrapClassLoader进行加载,这个时候BootstrapClassLoader发现这个类并不是自己需要去加载的类。就交给了ExtentionClassLoader类加载器进行加载,然后依次到ApplicationClassLoader进行加载。

这种机制的好处就是可以保证所有的类都可以被加载,并且不会出现重复加载的情况。什么意思呢?如果有一个类需要被加载,它执行到上层的类加载器的时候就会被加载,到下层类加载器中发现它被加载之后就不会再次加载,而每层的类加载器都有自己的职责,所以只完成对于自己该加载的类的加载操作。这样就不会出现,底层类加载器修改上层类加载器加载的类的操作,同时也就保证了类加载的安全性。防止核心API被改变。

相信有很多人在学习类加载机制的时候都想过自定义一个类加载器去修改别人的代码。这种方式是行不通的。

类加载器之间的关系

很多人在看到层次架构之后,就认为,类加载器之间存在父子继承的关系,其实不然。在双亲委派机制模型中只展示了一种类的层次关系,并不是体现继承关系。类加载器的拓展都是通过与父类的组合来实现的。如下,在ClassLoader类加载器中有如下一段代码,从中可以看出来,所有的继承的操作都是需要有一个父类的 ClassLoader。并且在使用继承操作的时候,必须先要有super()的父类构造。

public abstract class ClassLoader {

    // The parent class loader for delegation
    // Note: VM hardcoded the offset of this field, thus all new fields
    // must be added *after* it.
    private final ClassLoader parent;

如何实现双亲委派机制?

Java的类加载机制是由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) {
                long t0 = System.nanoTime();
                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.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
  • 第一步、先根据类名进行检查,该类是否被加载了。
  • 第二步、如果没有加载,则调用父类的loadClass()操作来进行加载
  • 第三步、如果父类加载器为BootstrapClassLoader或者是为空,则调用自己的loadClass()方法
  • 第四步、如果父类加载失败,抛出ClassNotFoundException异常后,再调用自己的findClass()方法进行加载。

总结

从上面的介绍中,我们了解了关于双亲委派机制的相关内容,并且通过源码来解释了如何实现双亲委派机制。在后续的分享中我们还会介绍关于双亲委派机制的扩展内容。以及如何实现自定义的类加载器等内容。希望大家多多关注,多多点赞支持

相关推荐

如何用 coco 数据集训练 Detectron2 模型?

随着最新的Pythorc1.3版本的发布,下一代完全重写了它以前的目标检测框架,新的目标检测框架被称为Detectron2。本教程将通过使用自定义coco数据集训练实例分割模型,帮助你开始使...

CICD联动阿里云容器服务Kubernetes实践之Bamboo篇

本文档以构建一个Java软件项目并部署到阿里云容器服务的Kubernetes集群为例说明如何使用Bamboo在阿里云Kubernetes服务上运行RemoteAgents并在agents上...

Open3D-ML点云语义分割实验【RandLA-Net】

作为点云Open3D-ML实验的一部分,我撰写了文章解释如何使用Tensorflow和PyTorch支持安装此库。为了测试安装,我解释了如何运行一个简单的Python脚本来可视化名为...

清理系统不用第三方工具(系统自带清理软件效果好不?)

清理优化系统一定要借助于优化工具吗?其实,手动优化系统也没有那么神秘,掌握了方法和技巧,系统清理也是一件简单和随心的事。一方面要为每一个可能产生累赘的文件找到清理的方法,另一方面要寻找能够提高工作效率...

【信创】联想开先终端开机不显示grub界面的修改方法

原文链接:【信创】联想开先终端开机不显示grub界面的修改方法...

如意玲珑成熟度再提升,三大发行版支持教程来啦!

前期,我们已分别发布如意玲珑在deepinV23与UOSV20、openEuler24.03发行版的操作指南,本文,我们将为大家详细介绍Ubuntu24.04、Debian12、op...

118种常见的多媒体文件格式(英文简写)

MP4[?mpi?f??]-MPEG-4Part14(MPEG-4第14部分)AVI[e?vi??a?]-AudioVideoInterleave(音视频交错)MOV[m...

密码丢了急上火?码住7种console密码紧急恢复方式!

身为攻城狮的你,...

CSGO丨CS2的cfg指令代码分享(csgo自己的cfg在哪里?config文件位置在哪?)

?...

使用open SSL生成局域网IP地址证书

某些特殊情况下,用户内网访问多可文档管理系统时需要启用SSL传输加密功能,但只有IP,没有域名和证书。这种情况下多可提供了一种免费可行的方式,通过openSSL生成免费证书。此方法生成证书浏览器会提示...

Python中加载配置文件(python怎么加载程序包)

我们在做开发的时候经常要使用配置文件,那么配置文件的加载就需要我们提前考虑,再不使用任何框架的情况下,我们通常会有两种解决办法:完整加载将所有配置信息一次性写入单一配置文件.部分加载将常用配置信息写...

python开发项目,不得不了解的.cfg配置文件

安装软件时,经常会见到后缀为.cfg、.ini的文件,一般我们不用管,只要不删就行。因为这些是程序安装、运行时需要用到的配置文件。但对开发者来说,这种文件是怎么回事就必须搞清了。本文从.cfg文件的创...

瑞芯微RK3568鸿蒙开发板OpenHarmony系统修改cfg文件权限方法

本文适用OpenHarmony开源鸿蒙系统,本次使用的是开源鸿蒙主板,搭载瑞芯微RK3568芯片。深圳触觉智能专注研发生产OpenHarmony开源鸿蒙硬件,包括核心板、开发板、嵌入式主板,工控整机等...

Python9:图像风格迁移-使用阿里的接口

先不多说,直接上结果图。#!/usr/bin/envpython#coding=utf-8importosfromaliyunsdkcore.clientimportAcsClient...

Python带你打造个性化的图片文字识别

我们的目标:从CSV文件读取用户的文件信息,并将文件名称修改为姓名格式的中文名称,进行规范资料整理,从而实现快速对多个文件进行重命名。最终效果:将原来无规律的文件名重命名为以姓名为名称的文件。技术点:...

取消回复欢迎 发表评论:

请填写验证码