当前位置:首页 > 科技  > 软件

三分钟带你搞懂双亲委派模型!

来源: 责编: 时间:2024-07-05 11:47:00 275观看
导读什么是双亲委派?在 Java 虚拟机中,任何一个类由加载它的类加载器和这个类一同来确立其唯一性。也就是说,JVM 对类的唯一标识,可以简单的理解为由ClassLoader id + PackageName + ClassName组成,因此在一个运行程序中有可能

什么是双亲委派?

在 Java 虚拟机中,任何一个类由加载它的类加载器和这个类一同来确立其唯一性。wOx28资讯网——每日最新资讯28at.com

也就是说,JVM 对类的唯一标识,可以简单的理解为由ClassLoader id + PackageName + ClassName组成,因此在一个运行程序中有可能存在两个包名和类名完全一致的类,但是如果这两个类不是由一个 ClassLoader 加载,会被视为两个不同的类,此时就无法将一个类的实例强转为另外一个类,这就是类加载器的隔离性。wOx28资讯网——每日最新资讯28at.com

为了解决类加载器的隔离问题,JVM 引入了双亲委派模型。wOx28资讯网——每日最新资讯28at.com

双亲委派模式,可以用一句话来说表达:任何一个类加载器在接到一个类的加载请求时,都会先让其父类进行加载,只有父类无法加载(或者没有父类)的情况下,才尝试自己加载。wOx28资讯网——每日最新资讯28at.com

大致流程图如下:wOx28资讯网——每日最新资讯28at.com

图片图片wOx28资讯网——每日最新资讯28at.com

使用双亲委派模式,可以保证,每一个类只会有一个类加载器。例如 Java 最基础的 Object 类,它存放在 rt.jar 之中,这是 Bootstrap 的职责范围,当向上委派到 Bootstrap 时就会被加载。wOx28资讯网——每日最新资讯28at.com

但如果没有使用双亲委派模式,可以任由自定义加载器进行加载的话,Java 这些核心类的 API 就会被随意篡改,无法做到一致性加载效果。wOx28资讯网——每日最新资讯28at.com

JDK 中ClassLoader.loadClass()类加载器中的加载类的方法,部分核心源码如下:wOx28资讯网——每日最新资讯28at.com

public Class<?> loadClass(String name) throws ClassNotFoundException {    return loadClass(name, false);}
protected Class<?> loadClass(String name, boolean resolve)        throws ClassNotFoundException{    // 1.首先要保证线程安全    synchronized (getClassLoadingLock(name)) {        // 2.先判断这个类是否被加载过,如果加载过,直接跳过        Class<?> c = findLoadedClass(name);        if (c == null) {            long t0 = System.nanoTime();            try {                // 3.有父类,优先交给父类尝试加载;如果为空,使用BootstrapClassLoader类加载器                if (parent != null) {                    c = parent.loadClass(name, false);                } else {                    c = findBootstrapClassOrNull(name);                }            } catch (ClassNotFoundException e) {                // 父类加载失败,这里捕获异常,但不需要做任何处理            }            // 4.没有父类,或者父类无法加载,尝试自己加载            if (c == null) {                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;    }}

如何自定义类加载器?

针对某些特定场景,比如通过网络来传输 Java 类的字节码文件,为保证安全性,这些字节码经过了加密处理,这时系统提供的类加载器就无法对其进行加载,此时我们可以自定义一个类加载器来完成文件的加载。wOx28资讯网——每日最新资讯28at.com

自定义类加载器也需要继承ClassLoader类,简单示例如下:wOx28资讯网——每日最新资讯28at.com

public class CustomClassLoader extends ClassLoader {    private String classPath;    public CustomClassLoader(String classPath) {        this.classPath = classPath;    }    @Override    protected Class<?> findClass(String name) throws ClassNotFoundException {        Class<?> c = findLoadedClass(name);        if (c == null) {            byte[] data = loadClassData(name);            if (data == null) {                throw new ClassNotFoundException();            }            return defineClass(name, data, 0, data.length);        }        return null;    }    protected byte[] loadClassData(String name) {        try {            // package -> file folder            name = name.replace(".", "//");            FileInputStream fis = new FileInputStream(new File(classPath + "//" + name + ".class"));            ByteArrayOutputStream baos = new ByteArrayOutputStream();            int len = -1;            byte[] b = new byte[2048];            while ((len = fis.read(b)) != -1) {                baos.write(b, 0, len);            }            fis.close();            return baos.toByteArray();        } catch (IOException e) {            e.printStackTrace();        }        return null;    }}

相关的测试类如下:wOx28资讯网——每日最新资讯28at.com

package com.example;public class ClassLoaderTest {    public static void main(String[] args) {        ClassLoader loader = Thread.currentThread().getContextClassLoader();        System.out.println("current loader:" +  loader);    }}

将ClassLoaderTest.java源文件放在指定目录下,并通过javac命令编译成ClassLoaderTest.class,最后进行测试。wOx28资讯网——每日最新资讯28at.com

public class CustomClassLoaderTest {    public static void main(String[] args) throws Exception {        String classPath = "/Downloads";        CustomClassLoader customClassLoader = new CustomClassLoader(classPath);        Class<?> testClass = customClassLoader.loadClass("com.example.ClassLoaderTest");        Object obj = testClass.newInstance();        System.out.println(obj.getClass().getClassLoader());    }}

输出结果:wOx28资讯网——每日最新资讯28at.com

com.example.CustomClassLoader@60e53b93

在实际使用过程中,最好不要重写loadClass方法,避免破坏双亲委派模型。wOx28资讯网——每日最新资讯28at.com

小结

双亲委派,指的是在接受类加载请求时,会让父类加载器试图加载该类,只有在父类加载器无法加载该类或者没有父类时,才尝试从自己的类路径中加载该类。wOx28资讯网——每日最新资讯28at.com

其次,针对某些场景,如果要实现类的隔离,可以自定义类加载器来实现特定类的加载。wOx28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-99021-0.html三分钟带你搞懂双亲委派模型!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Python 数值运算神器:15 个高效数学模块与函数

下一篇: 聊聊服务管理平台体系化建设和实践

标签:
  • 热门焦点
  • K60至尊版刚预热 一加Ace2 Pro正面硬刚

    Redmi这边刚如火如荼的宣传了K60 Ultra的各种技术和硬件配置,作为竞品的一加也坐不住了。一加中国区总裁李杰发布了两条微博,表示在自家的一加Ace2上早就已经采用了和PixelWo
  • 得物效率前端微应用推进过程与思考

    一、背景效率工程随着业务的发展,组织规模的扩大,越来越多的企业开始意识到协作效率对于企业团队的重要性,甚至是决定其在某个行业竞争中突围的关键,是企业长久生存的根本。得物
  • JavaScript学习 -AES加密算法

    引言在当今数字化时代,前端应用程序扮演着重要角色,用户的敏感数据经常在前端进行加密和解密操作。然而,这样的操作在网络传输和存储中可能会受到恶意攻击的威胁。为了确保数据
  • 这款新兴工具平台,让你的电脑效率翻倍

    随着信息技术的发展,我们获取信息的渠道越来越多,但是处理信息的效率却成为一个瓶颈。于是各种工具应运而生,都在争相解决我们的工作效率问题。今天我要给大家介绍一款效率
  • 使用AIGC工具提升安全工作效率

    在日常工作中,安全人员可能会涉及各种各样的安全任务,包括但不限于:开发某些安全工具的插件,满足自己特定的安全需求;自定义github搜索工具,快速查找所需的安全资料、漏洞poc、exp
  • 电视息屏休眠仍有网络上传 爱奇艺被质疑“薅消费者羊毛”

    记者丨宁晓敏 见习生丨汗青出品丨鳌头财经(theSankei) 前不久,爱奇艺发布了一份亮眼的一季报,不仅营收和会员营收创造历史最佳表现,其运营利润也连续6个月实现增长。自去年年初
  • 一条抖音4亿人围观 ! 这家MCN比无忧传媒还野

    作者:Hiu 来源:互联网品牌官01 擦边少女空降热搜,幕后推手曝光被网友誉为&ldquo;纯欲天花板&rdquo;的女网红井川里予,近期因为一组哥特风照片登上热搜,引发了一场互联网世界关于
  • 引领旗舰级影像能力向中端机普及 OPPO K11 系列发布 1799 元起

    7月25日,OPPO正式发布K系列新品—— OPPO K11 。此次 K11 在中端手机市场长期被忽视的影像板块发力,突破性地搭载索尼 IMX890 旗舰大底主摄,支持 OIS
  • onebot M24巧系列一体机采用轻薄机身设计,现已在各平台开售

    onebot M24 巧系列一体机目前已在线上线下各平台同步开售。onebot M24 巧系列采用一体化轻薄机身设计,最薄处为 10.15mm,拥有宝石红、午夜蓝、石墨绿、雅致
Top