深入理解Java类加载机制中的双亲委派模型--根据源码探讨

这篇具有很好参考价值的文章主要介绍了深入理解Java类加载机制中的双亲委派模型--根据源码探讨。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:
今天和大家探讨一道Java中经典的面试题,这道面试题经常出现在各个公司的面试中,本篇文章主要讲解ava类加载机制中的双亲委派模型的知识。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读。

如果文章有什么需要改进的地方欢迎大佬提出,对大佬有帮助希望可以支持下哦~

小威在此先感谢各位小伙伴儿了😁

深入理解Java类加载机制中的双亲委派模型--根据源码探讨,秋招总结&小白入坑Java,java,python,开发语言,原力计划

以下正文开始

Java中的类加载器

在介绍双亲委派模型之前,首先先介绍下Java中的类加载器。
深入理解Java类加载机制中的双亲委派模型--根据源码探讨,秋招总结&小白入坑Java,java,python,开发语言,原力计划

启动类加载器(Bootstrap ClassLoader)

首先先介绍下类加载器中的重量级器物,就是大名鼎鼎–启动类加载器。

为什么说他是重量级的恩,因为它是Java类加载器层次结构的最顶层,由虚拟机实现,用于加载Java核心类库,如java.lang和java.util等。

既然是最顶层的类加载器,我们就康康它有什么作用:

启动类加载器是由C/C++编写的,无法直接在Java代码中获取其引用。 它负责加载Java运行时环境所需的基本类。

扩展类加载器(Extension ClassLoader)

接着我们看一下Java加载器中的第二号人物–扩展类加载器。

扩展类加载器是由Java编写的,它是启动类加载器的子类。 它负责加载Java扩展类库,位于jre/lib/ext路径下的JAR文件。
扩展类加载器可以通过java.ext.dirs系统属性来指定其他目录作为扩展类库的路径。

应用程序类加载器(Application ClassLoader)

接着介绍最底层的加载器–应用程序类加载器。

应用程序类加载器是Java类加载器层次结构的最底层,也称为系统类加载器。
它负责加载应用程序类路径(Classpath)下的类,包括开发者自己编写的类和第三方库。
应用程序类加载器可以通过-classpath或-cp选项来指定加载类的路径。

自定义类加载器(Custom ClassLoader)

除了上述系统类的加载器,我们开发者还可以自定义加载器-惊不惊喜,意不意外。

深入理解Java类加载机制中的双亲委派模型--根据源码探讨,秋招总结&小白入坑Java,java,python,开发语言,原力计划

自定义类加载器是开发者根据需求编写的自定义加载器,继承自ClassLoader类
它可以根据特定的加载规则和需求,从不同的来源加载类,比如本地文件系统、网络等。
自定义类加载器需要实现findClass()方法,指定类的加载规则,然后通过defineClass()方法加载类的字节码。

双亲委派模型

看到这里,上我们的重头菜,这块知识是面试中的重点内容。

深入理解Java类加载机制中的双亲委派模型--根据源码探讨,秋招总结&小白入坑Java,java,python,开发语言,原力计划

双亲委派(Parent Delegation)是Java类加载机制中一种重要的实现方式,它通过一种递归的方式在类加载器之间建立了父子关系,并且定义了类加载的优先级。该模型主要用于解决类加载的冲突和隔离问题,保证Java应用程序的稳定性和安全性。

在Java类加载机制中,每个类加载器都有一个父加载器。当一个类加载器需要加载一个类时,它首先会委托给它的父加载器进行加载。只有当父加载器无法加载时,子加载器才会尝试加载。这种递归的委派模型可以形成一个类加载器的层次结构,称为类加载器树。

我看了《深入理解Java虚拟机-第三版》中的讲解,挺详细的,这里分享给大家:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父类加载器反馈自己无法加载这个请求时,子加载器才会尝试自己去加载。
深入理解Java类加载机制中的双亲委派模型--根据源码探讨,秋招总结&小白入坑Java,java,python,开发语言,原力计划

双亲委派模型源码

首先可以先尝试自己看下源码,非常通俗易懂:

protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    // 首先,检查类是否已经被加载
    Class<?> c = findLoadedClass(name);
    
    if (c == null) {
        try {
            if (parent != null) {
                // 如果父类加载器存在,则委派给父类加载器
                c = parent.loadClass(name, false);
            } else {
                // 否则,使用引导类加载器进行加载
                c = findBootstrapClassOrNull(name);
            }
        } catch (ClassNotFoundException e) {
            // 如果父类加载器也无法找到类,则尝试自己加载
            c = findClass(name);
        }
    }
    
    if (resolve) {
        resolveClass(c);
    }
    
    return c;
}

在上面的源码中,我们可以看到双亲委派机制的体现。当loadClass方法被调用时,首先会检查该类是否已经被加载。如果没有加载,那么会按照以下步骤进行处理:

  1. 首先,调用findLoadedClass(name)方法检查类是否已经被其他类加载器加载过。如果是,则直接返回该类的Class对象。

  2. 如果这个类还未加载,则尝试委派给父类加载器加载。通过parent.loadClass(name, false)方法,将类加载任务传递给父类加载器。这个过程中,父类加载器会重复执行上述流程,直到达到引导类加载器为止。

  3. 如果所有的父类加载器都无法加载该类,那么会尝试使用启动类加载器加载。这是Java类加载器层次结构的最顶层。

  4. 如果引导类加载器仍然无法找到所需的类,就会调用findClass(name)方法在当前类加载器的作用域内查找并加载该类。

  5. 到最后,如果resolve参数为true,就会调用resolveClass©方法进一步解析和链接该类。

深入理解Java类加载机制中的双亲委派模型--根据源码探讨,秋招总结&amp;小白入坑Java,java,python,开发语言,原力计划

如何打破双亲委派模型

其实双亲委派模型并不是具有强制性约束的模型,虽然它有助于保证类的隔离和加载的顺序,但有时候我们可能需要打破这种机制,比如我们在特殊情况下需要自定义类加载逻辑或实现热部署的时候。

上周面试问道了这个问题,所以在这里也介绍几种打破Java中双亲委派机制的方法:

  1. 自定义类加载器:我们自定义一个继承自ClassLoader的类加载器,重写loadClass方法,可以实现自己的类加载逻辑。在我们定义的这个方法中,可以在需要时跳过父类加载器并直接加载类,从而打破双亲委派机制。但是,在自定义类加载器中打破双亲委派机制可能会导致类的隔离性和安全性问题,所以我们在使用时要慎重。

  2. 线程上下文类加载器:Java中提供了线程上下文类加载器(Thread Context ClassLoader)的概念,它可以在某些情况下打破双亲委派机制。例如,在JNDI、SPI(Service Provider Interface)和一些框架中,线程上下文类加载器可以用来加载指定的类,从而不受双亲委派机制的限制。

  3. 通过反射机制:使用反射机制可以直接调用Class类的defineClass方法,这样可以绕过双亲委派机制直接加载指定的类。但是,在使用这种方式时,我们需要自行处理类加载的顺序和依赖关系,因为双亲委派机制不再起作用。

综上所述,不正确地使用或滥用这些方法可能导致类加载冲突、安全问题以及代码的不稳定性 ,因此我们还需要在明确的需求和充分的理解下使用(面试会背诵就行【手动狗头】)。

深入理解Java类加载机制中的双亲委派模型--根据源码探讨,秋招总结&amp;小白入坑Java,java,python,开发语言,原力计划
文章到这里就先结束了,感兴趣的可以订阅专栏哈,后续会继续分享相关的知识点。

深入理解Java类加载机制中的双亲委派模型--根据源码探讨,秋招总结&amp;小白入坑Java,java,python,开发语言,原力计划文章来源地址https://www.toymoban.com/news/detail-619645.html

到了这里,关于深入理解Java类加载机制中的双亲委派模型--根据源码探讨的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 类加载 - 双亲委派机制详解

    启动类加载器(Bootstrap Class Loader):它是Java虚拟机的一部分,负责加载Java核心类库,如java.lang包中的类。它是最顶层的类加载器,由C++实现,不是Java类。 扩展类加载器(Extension Class Loader):它负责加载Java的扩展类库,位于JRE的lib/ext目录下。它是由Java编写的类加载器,是

    2024年02月12日
    浏览(31)
  • JVM:双亲委派机制&类加载器

    Java运行时环境有一个 java.lang 包,里面有一个 ClassLoader 类 我们自定义一个 String 类在 java.lang 包下,下面的main方法报错。原因是: 根据双亲委派机制,会向上找先是找到了 应用程序加载器(appClassLoader) ,然后向上找 扩展类加载器(ExtClassLoader) ,最后找 根类加载器(Boot Strap

    2024年02月01日
    浏览(27)
  • JVM类加载和双亲委派机制

    当我们用java命令运行某个类的main函数启动程序时,首先需要通过类加载器把类加载到JVM,本文主要说明类加载机制和其具体实现双亲委派模式。 类加载过程 : 类加载的过程是将类的字节码加载到内存中的过程,主要包括:加载--链接--初始化,其中链接还包括验证、准备、

    2024年02月09日
    浏览(32)
  • JVM(类的加载与ClassLoader、双亲委派机制)

    类在内存中完整的生命周期: 加载--使用--卸载 。其中加载过程又分为: 装载、链接、初始化 三个阶段。 当程序主动使用某个类时,如果该类还未被加载到内存中,系统会通过加载、链接、初始化三个步骤来对该类进行初始化。如果没有意外,JVM将会连续完成这三个步骤,

    2024年02月03日
    浏览(33)
  • 【JVM从入门到实战】(六)类加载器的双亲委派机制

    在Java中如何使用代码的方式去主动加载一个类呢? 方式1:使用Class.forName方法,使用当前类的类加载器去加载指定的类。 方式2:获取到类加载器,通过类加载器的loadClass方法指定某个类加载器加载。 双亲委派机制: 自底向上查找是否加载过,再由顶向下进行加载 面试题:

    2024年02月04日
    浏览(39)
  • JVM类加载基本流程及双亲委派模型

    一个运行起来的Java进程就是一个JVM虚拟机,这就需要从操作系统中申请一片内存区域。JVM申请到内存之后,会把这个内存划分为几个区域,每个区域都有各自的作用。 一般会把内存划分为 四个区域 : 方法区 (也称 \\\"元数据区\\\"), 堆区 , 栈区 , 程序计数器 。 (1)方法区:

    2024年04月23日
    浏览(32)
  • JVM的类加载的过程以及双亲委派模型

    目录 1、加载 (加载字节码文件,生成.class对象) 2、验证(验证Class文件是否符合规范)  3、准备 (为静态变量分配内存并设置变量初始值) 4、解析(初始化常量池中的一些常量)  5、初始化(初始化对象,并为静态变量赋值)  总结: 双亲委派模型:   JVM的类加载器

    2023年04月20日
    浏览(34)
  • 深度解析JVM类加载器与双亲委派模型

    Java虚拟机(JVM)是Java程序运行的核心,其中类加载器和双亲委派模型是JVM的重要组成部分。本文将深入讨论这两个概念,并解释它们在实际开发中的应用。 1. 什么是类加载器? 类加载器是JVM的一部分,负责加载Java类的字节码文件。Java应用程序中的每个类都必须由类加载器

    2024年01月17日
    浏览(40)
  • [JVM] 3. 类加载子系统(2)-- 类加载器、双亲委派机制(JDK1.8及之前)及其他

    JDK1.8及之前和JDK9及之后的双亲委派模型是不一样的,这里学习了1.8及以前的双亲委派模型,记录笔记 1.8之前主要是这几种类加载器: 负责将存放在 JAVA_HOMElib 目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的(仅按照文件名,如rt.jar)类库加载到虚

    2024年02月16日
    浏览(38)
  • Java双亲委派和类加载器

    Java类加载分为以下几个步骤: 只有 加载步骤 中的 读取二进制流与初始化部分 ,能够被上层开发者,也就是大部分的Java程序员控制,而 剩下的所有步骤 ,都是由JVM掌控,其中细节由JVM的开发人员处理,对上层开发者来说是个黑盒。 面向对象SOLID: 单一功能、 开闭 、里氏替

    2023年04月26日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包