类加载器与双亲委派模型

类加载机制和双亲委派模型 阅读详情

1. 双亲委派模型

1.1 什么是双亲委派模型

首先,先要知道什么是类的加载器。简单说,类加载器就是根据指定全限定名称将class文件加载到JVM内存,装维Class对象。如果站在JVM的角度来说,只存在两种加载器:

  • 启动类加载器(Bootstrap ClassLoader):由C++语言实现(针对HotSpot),负责将存放在\lib目录或-Xbootclasspath参数指定路径中的类库加载到内存中。
  • 其他类型加载器:由Java语言实现,继承自抽象类ClassLoader。如:
    • 扩展类加载器(Extension ClassLoader):负责加载\lib\ext目录或java.ext.dirs系统便令指定的路径中的所有类库。
    • 应用程序类加载器(Application ClassLoader)。负责加载用户类路径(classpath)上的指定类库,我们可以直接使用这个类加载器。一般情况,如果我们没有自定义类加载器默认就是用这个加载器。

双亲委派模型工作过程:如果一个类加载器收到类加载的请求,它首先不会自己去尝试加载中这个类,而是把这个请求委派给父类加载器完成。每个类加载器都是如此,只有当父加载器在及其的搜索范围内找不到指定的类时(即ClassNotFoundException),子加载器才会尝试自己去加载。

1.2 为什么需要双亲委派模型?

为什么需要双亲委派模型呢?假设没有双亲委派模型,试想一个场景:

黑客自定义一个java.lang.String类,该String类具有系统的String类一样的功能,只是在某个函数稍作修改。比如equals函数,这个函数经常使用,如果在这个函数中,黑客加入一些“病毒代码”。并通过自定义类加载器加入到JVM中。此时,如果没有双亲委派模型,那么JVM就可能误以为黑客自定义的java.lang.String类是系统的String类,导致“病毒代码”被执行。

而有了双亲委派模型,黑客自定义的java.lang.String永远不会被加载到内存中。因为首先是最顶端的类加载器加载系统的java.lang.String类,最终自定义的类加载器无法加载java.lang.String类。

或许你会想,我在定义的类加载器里面强制加载自定义的java.lang.String类,不去通过调用父加载器不就好了吗?的确,这样是可行的。但是,在JVM中,判断一个对象是否是某个类型时,如果该对象的实际类型与带比较类型的类加载器不同,那么会返回false。

举个栗子:

ClassLoader1、ClassLoader2都加载java.lang.String类,对应Class1,、Class2对象。那么Class1对象不属于ClassLoader2对象加载的java.lang.String类型。

2. 自定义类加载器

2.1 几个重要函数

loadClass默认实现如下:

public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
}

再看看loadClass(String name, boolean resolve) 函数:

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(String,boolean)函数即实现了双亲委派模型,整个大致过程如下:

  1. 首先,检查下制定名称的类是否已经加载过,如果加载过了,就不需要再加载,直接返回。
  2. 如果此类没有加载过,那么,再判断下是否有父加载器;如果有父加载器,则由父加载器加载(即调用parent.ladClass(name,false);)或者是调用bootstrap类加载器来加载。
  3. 如果父加载器及bootstrap类加载器都没有找到指定的类,那么调用当前类加载器的findClass方法来完成类加载。

换句话说,如果自定义类加载器,就必须重写findClass方法!

find Class

findClass的默认实现如下

protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
}

可以看出,抽象类ClassLoader的findClass函数默认是抛出异常的。而前面我们知道,loadClass在父加载器无法加载类的时候,就会降低用我们自定义的类加载器中的findClass函数,因此我们必须在loadClass这个函数里面实现将一个指定类名称转换为class对象。

如果是读取一个指定的名称的类为字节数组的话,这个很好办。但是如何将字节数组转为class对象呢?很简单,Java提供了defineClass方法,通过这个方法,就可以把一个字节数组转为Class对象了。

defineClass

defineClass主要的功能是:

将一个字节数组转为Class对象,这个字节数组是class文件读取后最终的字节数组。如,假设class文件时加密过的,则需要解密后作为形参传入defineClass函数。

defineClass默认实现如下:

protected final Class<?> defineClass(String name, byte[] b, int off, int len)
        throws ClassFormatError  {
        return defineClass(name, b, off, len, null);
}

2.2 函数调用过程

手把手教你用高频注入法辨识永磁同步电机电感参数(附MATLAB仿真) 本文详细介绍了高频注入法在永磁同步电机电感参数辨识中的工程实践与MATLAB仿真指南。通过高频信号注入法,无需拆解电机即可在线精确测量Ld和Lq参数,适用于电动汽车驱动和工业伺服等高精度控制场景。文章包含信号设计、硬件实现、解调算法及完整MATLAB仿真模型构建,帮助工程师快速掌握这一关键技术。 阅读详情

相关推荐

将点云坐标转换成世界坐标的demo

将点云坐标转换成世界坐标的demo

howard789的博客 2206

类加载器 - 双亲委派模型

学习与思考Java类加载中的双亲委派模型,加入一些源码分析,demo编码

蒋大钊的博客 575

ARM CoreSight架构

CoreSight架构是现代复杂SoC的“飞行数据记录仪”(黑匣子)和“精密诊断仪”的结合体。它彻底改变了嵌入式系统的调试方式,从传统的“盲人摸象”变成了拥有“上帝视角”,是ARM生态系统能够支撑起从微控制器到高性能服务器芯片如此广泛产品线的重要基石技术之一。

guigenyi的专栏 1420

什么是双亲委派模型?双亲委派模型有何作用?

什么是双亲委派模型?双亲委派模型有何作用?

吴名氏的博客 13万+

dell r630 配置raid_DELL服务器RAID配置图文教程

名称解释:Disk Group:磁盘组,这里相当于是阵列,例如配置了一个RAID5,就是一个磁盘组VD(Virtual Disk): 虚拟磁盘,虚拟磁盘可以不使用阵列的全部容量,也就是说一个磁盘组可以分为多个VDPD(Physical Disk): 物理磁盘HS:Hot Spare 热备Mgmt:管理【一】创建逻辑磁盘1、按照屏幕下方的虚拟磁盘管理器提示,在VD Mgmt菜单(可以通过CTRL+P...

weixin_33253741的博客 3510

Node.js内存溢出?一招搞定JavaScript heap out of memory错误(附永久配置方案)

本文深入解析Node.js内存溢出问题,提供从临时调整到永久配置的完整解决方案。重点介绍通过设置`max-old-space-size`参数和`NODE_OPTIONS`环境变量来扩展JavaScript堆内存限制,适用于Webpack、Vite等构建工具的大型项目场景,并涵盖Windows、Linux/macOS多平台配置方法。

cake8的博客 1053

类加载器双亲委派模型

类加载器双亲委派模型是Java类加载器的一种工作机制。它基于一种层次化的类加载器结构,通过委派的方式实现类的加载和查找。在这个模型中,每个类加载器都有一个父类加载器,当一个类加载器需要加载一个类时,它首先将加载请求委派给父类加载器,只有当父类加载器无法完成加载任务时,才由当前类加载器自己去加载。类加载器双亲委派模型是Java类加载器的一种工作机制,通过委派的方式实现类的加载和查找。它通过隔离命名空间、提高安全性和鼓励代码复用等方式,为Java程序提供了良好的类加载机制。

果酱 の 博客 3308

Debian 11 下用hostapd+dnsmasq搭建WiFi热点:从命令行到实战(避坑指南)

本文详细介绍了在Debian 11系统上,使用hostapd和dnsmasq从命令行搭建稳定WiFi热点的完整实战流程。内容涵盖环境准备、无线网卡AP模式检查、服务深度配置,并重点提供了从服务启动失败到客户端无法上网等常见问题的系统性排错指南,帮助用户避开配置陷阱,成功创建可用的无线接入点。

CAT789的专栏 769

Java高级——类加载器和双亲委派模型

为了避免破坏双亲委派模型,JDK1.2新增protect的findClass()方法,让用户尽可能重写findClass()而不是loadClass(),这样既不影响用户自定义加载类,又可保证新写的类加载器符合双亲委派模型。这是一种由父类加载器去请求子类加载器完成类加载的行为,打通了双亲委派模型的层次结构来逆向使用类加载器,典型应用有JNDI、JDBC等。,如对于Object,无论哪个类加载器加载,最终都委派给启动类加载器,从而保证了唯一性。除了启动类加载器外,其余的类加载器都有自己的父类加载器,

松仔Log的博客 821

基于LLaMA-action模型的文档摘要任务微调

文档摘要是指从长文档中提取关键信息,生成简短而准确的总结。抽取式摘要:从原文中直接抽取关键句子或短语组成摘要。生成式摘要:通过生成新的句子来表达原文的核心内容。混合式摘要:结合抽取式和生成式方法,既保留原文的关键句子,又生成新的内容。新闻网站:自动生成新闻摘要,帮助用户快速了解新闻要点。社交媒体:为用户提供新闻摘要,便于分享和传播。学术搜索引擎:为用户提供学术文献的摘要,帮助用户快速筛选相关文献。学术写作辅助:帮助研究人员快速生成文献综述部分。企业内部文档管理:自动生成文档摘要,便于员工快速了解文档内容。

加入“Super Entity”,与全能开发团队共探AI智能体与数字人项目,开启前沿技术之旅。 1430

手把手教你学PCIE-- 热插拔电路设计与实现方案

PCIe热插拔(Hot-Plug)技术允许用户在系统运行时安全地插入或移除设备,而无需重启系统。本文将深入讲解热插拔电路的设计要点、关键器件选型及信号协议规范,涵盖机械结构、电气保护和电源管理三大核心模块。​。

MHD0815的博客 440

Java的类加载器与双亲委派模型详解

Java的双亲委派模型以及类加载器介绍

愿你我都能实现自己的梦想 1433

使用HART Server PC软件进行HART设备的组态、调试和分析的完整指南

HART协议是一种用于工业自动化中的双向通信协议,能够在4-20mA模拟信号的基础上叠加数字信号,从而实现设备的远程监控和管理。HART协议兼具模拟和数字通信的优点,被广泛应用于过程控制系统中。设备组态:通过软件可以对HART设备进行组态,配置设备参数。设备调试:支持设备的在线调试和故障诊断,方便快速解决问题。数据分析:提供设备运行数据的实时监控和历史数据分析功能。报表生成:支持生成各类报表,便于数据记录和管理。

qq_38334677的博客 2468

7. JVM类加载器与双亲委派模型

Java类加载器是JVM的核心组件,负责将字节码文件加载为Class对象。主要包含启动类加载器(加载核心库)、扩展类加载器(加载ext目录)、应用类加载器(加载classpath)和自定义类加载器。双亲委派模型是其工作机制:加载请求先委托父加载器处理,父类无法完成时才由子类处理。该机制确保核心API安全、避免重复加载,保证类唯一性和类型安全。Java9后目录结构简化,不再单独保留jre目录。

weixin_73692078的博客 968

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【深入理解JVM】:类加载器与双亲委派模型

类加载器 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因。在类加载的第一阶段“加载”过程中,需要通过一个类的全限定名来获取定义此类的二进制字节流,完成这个动作的代码块就是类加载器。这一动作是放在Java虚拟机外部去实现的,以便让应用程序自己决定如何获取所需的类。 虚拟机规范并没有指明二进制字节流要从一个Class文件获取,或者说

smile4lee的博客 7万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

JVM 类加载器与双亲委派模型

1. 类加载器 我们知道,虚拟机在加载类的过程中需要使用类加载器进行加载,而在 Java 中,类加载器有很多,那么当 JVM 想要加载一个.class文件的时候,到底应该由哪个类加载器加载呢?这时候就需要双亲委派机制来告诉 JVM 使用哪个类加载器加载。在讲解什么是双亲委派机制之前,我们先看一下有哪些加载器。 从 Java 虚拟机的角度来讲,只存在两种不同的类加载器:一种是启动类加载器 Bootstrap ClassLoader,这个类加载器使用 C++ 语言实现,是虚拟机自身的一部分;另一种就是所..

a6636656的博客 155

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

深度解析Java类加载器机制与双亲委派模型

Java类加载器是JVM的核心组件,遵循双亲委派模型实现类的动态加载。系统包含启动类加载器(Bootstrap)、扩展类加载器(Extension)和应用类加载器(Application)三级结构,同时支持自定义类加载器。双亲委派通过父加载器优先机制保证安全性和类唯一性,但存在SPI、模块化系统等需要打破该模型的场景。类加载过程涉及loadClass、findClass等核心方法,开发者可通过继承ClassLoader实现自定义加载逻辑。

m0_66884848的博客 1061

Java类加载器与双亲委派模型

一.加载类的开放性                在类加载的第一阶段”加载“过程中,需要通过一个类的全限定名获取定义此类的二进制流,完成这个动作的代码块就是类加载器。这一部在JVM之外实现,方便应用程序自己决定如何获取所需的类。        这个获取二进制流有很多途径和方向:        1.从ZIP包中获取,成为JAR,EAR,WAR格式的基础。        2.从网络中获取,典型应用Ap...

xiaoyangchun的博客 991

深度解析JVM类加载器与双亲委派模型

Java虚拟机(JVM)是Java程序运行的核心,其中类加载器和双亲委派模型是JVM的重要组成部分。本文将深入讨论这两个概念,并解释它们在实际开发中的应用。类加载器是JVM的一部分,负责加载Java类的字节码文件。Java应用程序中的每个类都必须由类加载器加载,类加载器将类的字节码文件从磁盘或网络加载到内存中,并在JVM中创建一个对应的Class对象。双亲委派模型是一种类加载器之间的层次结构,它通过父类加载器委派给子类加载器加载类。

weixin_43268715的博客 2380

双亲委派模型与类加载器

双亲委派模型与类加载器写在最前一.类加载器1.什么是类加载器2.类加载器的作用3.常见的类加载器二.双亲委派模型1.为什么需要双亲委派模型2.什么是双亲委派模型3.双亲委派模型的工作过程4.双亲委派模型的优点5.破坏双亲委派模型全文总结 写在最前 我们都知道类都是通过类加载器被加载进虚拟机中的,那这个类加载器有哪些呢?我们平时写的代码又是通过什么类加载器被加载进虚拟机中的呢?类加载器的工作模式又是什么呢?带着疑问一起去学习下双亲委派模型与类加载器。 一.类加载器 1.什么是类加载器 我们都知道java文件的

初心不忘、始终方得 867
上一篇: 带你简单理解Binder
下一篇: 对生活的一点感慨
Bobby_lyc
博客等级 码龄16年 1164粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值