自定义类加载器及其双亲委托机制

2023-05-16

自定义类加载器及其双亲委托机制

    • JAVA自带的类加载器
    • 自定义类加载器
      • 代码示例
    • 双亲委托机制

JAVA自带的类加载器

JAVA的类加载器分为三种,启动类加载器(系统类加载器)、扩展类加载器以及系统类加载器
由前到后每一个都是下一个的父加载器
获取类加载器以及加载器的加载路径

		System.out.println("----------------三种类加载器-------------------");
        System.out.println(Launcher.getLauncher().getClassLoader());
        // 启动类加载器输出为空,别慌不是你错了,这就是正确结果
        System.out.println(Launcher.getLauncher().getClassLoader().getParent());
        System.out.println(Launcher.getLauncher().getClassLoader().getParent().getParent());
        System.out.println("---------------------各个类加载的路径---------------------------");
        System.out.println(System.getProperty("sun.boot.class.path"));
        System.out.println(System.getProperty("java.ext.dirs"));
        System.out.println(System.getProperty("java.class.path"));

输出结果

----------------三种类加载器-------------------
sun.misc.Launcher$AppClassLoader@14dad5dc
sun.misc.Launcher$ExtClassLoader@74a14482
null
---------------------各个类加载的路径---------------------------
C:\Java\jdk1.8.0_65\jre\lib\resources.jar;C:\Java\jdk1.8.0_65\jre\lib\rt.jar;C:\Java\jdk1.8.0_65\jre\lib\sunrsasign.jar;C:\Java\jdk1.8.0_65\jre\lib\jsse.jar;C:\Java\jdk1.8.0_65\jre\lib\jce.jar;C:\Java\jdk1.8.0_65\jre\lib\charsets.jar;C:\Java\jdk1.8.0_65\jre\lib\jfr.jar;C:\Java\jdk1.8.0_65\jre\classes
C:\Java\jdk1.8.0_65\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
C:\Java\jdk1.8.0_65\jre\lib\charsets.jar;C:\Java\jdk1.8.0_65\jre\lib\deploy.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\access-bridge-64.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\cldrdata.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\dnsns.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\jaccess.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\jfxrt.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\localedata.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\nashorn.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\sunec.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\sunjce_provider.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\sunmscapi.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\sunpkcs11.jar;C:\Java\jdk1.8.0_65\jre\lib\ext\zipfs.jar;C:\Java\jdk1.8.0_65\jre\lib\javaws.jar;C:\Java\jdk1.8.0_65\jre\lib\jce.jar;C:\Java\jdk1.8.0_65\jre\lib\jfr.jar;C:\Java\jdk1.8.0_65\jre\lib\jfxswt.jar;C:\Java\jdk1.8.0_65\jre\lib\jsse.jar;C:\Java\jdk1.8.0_65\jre\lib\management-agent.jar;C:\Java\jdk1.8.0_65\jre\lib\plugin.jar;C:\Java\jdk1.8.0_65\jre\lib\resources.jar;C:\Java\jdk1.8.0_65\jre\lib\rt.jar;E:\亿达信息\GoodGoodStadyDayDayUp\out\production\GoodGoodStadyDayDayUp;E:\亿达信息\GoodGoodStadyDayDayUp\lib\mysql-connector-java-5.0.8-bin.jar;E:\idea\IntelliJ IDEA 2017.2\lib\idea_rt.jar

在这些路径中(每个人的也许会不同,所以按照自己的来修改),可以尝试把自己写的Class放入到指定的文件中(ExtClassLoader只加载Jar包中的类),去通过getClassLoader()方法获取已验证结果,这里不做过多介绍。
如果你很好奇我怎么知道获取路径的是这些参数,那就请参考一下sun.misc.Launcher源代码。。。

自定义类加载器

代码示例

package com.programer.wenbin.jvm;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader {

    private String path;
    private String classLoaderName;
    private final String fileExtension = ".class";

    public MyClassLoader(String classLoaderName) {
        super();// 使用系统类加载器作为父加载器
        this.classLoaderName = classLoaderName;
    }

    public MyClassLoader(ClassLoader parent, String classLoaderName) {
        super(parent);// 使用传入的类加载器作为父加载器
        this.classLoaderName = classLoaderName;
    }

    /**
     * 根据文件的地址,以字节的形式加载class文件。
     *
     * @param {String}name
     * @return 加载class的byte数组
     */
    private byte[] loadClassData(String name) {
        InputStream is = null;
        byte[] data = null;
        ByteArrayOutputStream baos = null;
        try {
            name = name.replace(".", "\\");
            is = new FileInputStream(new File(this.path + name + this.fileExtension));
            baos = new ByteArrayOutputStream();
            int ch = 0;
            while (-1 != (ch = is.read())) {
                baos.write(ch);
            }
            data = baos.toByteArray();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                is.close();
                baos.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return data;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        System.out.println("----------------------This is MyClassLoader------------------");
        byte[] data = this.loadClassData(name);
        return super.defineClass(name, data, 0, data.length);
    }

    public void setPath(String path) {
        this.path = path;
    }
}


打开ClassLoader类会看到注释中解释了怎么建立了一个简单的自定义加载器
测试加载器

 		MyClassLoader loader = new MyClassLoader("loader1");
        loader.setPath("C:\\Users\\13559\\Desktop\\jvmtest\\");
        // com.programer.wenbin.jvm.TestUse这个类是自己建立的一个普通java类,可以没有任何一个属性和方法
        Class<?> clazz = loader.loadClass("com.programer.wenbin.jvm.TestUse");
        System.out.println(clazz.getClassLoader());

setPath是这只一个加载的路径我们把需要加载的类放入进去即可,如下图
在这里插入图片描述
测试已经准备好,准备你们的小手点击运行,那么问题来了!
sun.misc.Launcher$AppClassLoader@14dad5dc
这输出的怎么是AppClassLoader(系统类加载器),这也就是今天要说的重点双亲委托机制

双亲委托机制

  • 概念
    当使用一个类加载器去加载一个class对象的时候,这个加载器会用自己的父类加载器去尝试加载,如果加载不成功才会自己去加载
    在这里插入图片描述
    会发现递归调用,这也就是双亲委托的核心代码
  • 啃老的好处
    这里有一个命名空间的概念,我以后可能会专门发一个关于这个的,如果没有(懒了),请大家去CSDN中进行搜索。这里简要的说一下:
    命名空间是由加载器以及所有的父类加载器所组成的,自加载器可以访问父类加载的类,父类加载器不能访问子加载器加载的类,儿子可以用爸爸的,爸爸不可以用儿子的,兄弟之间的也是不可以用的,由此可以得出结论加载器的一家过的很不和谐
    …有点说多了,简单的说一下好处吧,这样就能保证JAVA的核心类,比如最牛*的Object类,是由启动类加载器加载的,这样使的Object只加载一次,因为如果已经加载过的类,并且是可见的,那么就不会再一次加载,“开箱即用”。如果对于这个类不可见的话,就会再一次加载Obejct,所以存在很多版本的Object类,使得程序存在潜在风险(JDK设计人员的脑子牛!),但是这种也不是万能的,比如JDBC等,所以有的时候会违背双亲委托机制,会使用线程上下文类加载器,以后别的文章会说。

如果想用自己的类加载器加载,怎么办呢?
上面开始提到过AppClassLoader的加载路径,那么我们就把已经编译好的文件删除掉去运行,如果是ecplise就打开文件夹进行删除,idea在目录里进行删除即可

在这里插入图片描述
删除之后请大家再次运行
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义类加载器及其双亲委托机制 的相关文章

  • SQL中case when用法详解及使用案例

    一 语法 Case具有两种格式 简单Case函数和Case搜索函数 简单Case函数格式 xff1a CASE 列名 WHEN 条件值1 THEN 选项1 WHEN 条件值2 THEN 选项2 ELSE 默认值 END Case搜索函数 x
  • 想入行C++游戏脚本制作?首先听听7年经验大佬怎么说?

    先自我介绍一下 xff0c 七年的程序开发经验 xff0c 在小一线城市税后2W多点 xff0c 本应过着很舒适的生活 xff0c 每天喝点小酒 xff0c 玩玩游戏 但自从入了A股 xff0c 一切都改变了 xff0c 如今的我 xff0
  • 大学刚毕业,用10000小时,走进字节跳动拿了offer

    前言 xff1a 没有绝对的天才 xff0c 只有持续不断的付出 对于我们每一个平凡人来说 xff0c 改变命运只能依靠努力 43 幸运 xff0c 但如果你不够幸运 xff0c 那就只能拉高努力的占比 2020年7月 xff0c 我有幸成
  • tensorflow中tfrecord数据操作

    前言 xff1a 为了更加展示tfrecord数据的相关操作 xff0c 笔者后续又写了一个实践的简单例子进一步解释 xff0c 具体可以看 xff1a TFrecords 制作数据集小例子 xff08 多标签 xff09 爱吃火锅的博客
  • 软件测试阶段

  • VR技术类毕业论文文献有哪些?

    本文是为大家整理的VR技术主题相关的10篇毕业论文文献 xff0c 包括5篇期刊论文和5篇学位论文 xff0c 为VR技术选题相关人员撰写毕业论文提供参考 1 期刊论文 运动炫科技 智慧赢未来 VR技术在体育领域内的应用与展望 期刊 xff
  • CentOS7防火墙添加端口

    CentOS7防火墙添加端口 CentOS防火墻添加端口比较简单 xff0c 三步走 xff08 皆以root用户执行 xff0c 或者用sudo命令 xff09 xff1a 1 查看开发的端口 firewall span class to
  • 手写一个--生产者消费者模式

    文章目录 前言wait notify方法实现生产者消费者模型1 使用Object的wait notify 方法2 使用Lock和Condition的await signal 方法3 使用BlockingQueue阻塞队列方法 前言 生产者消
  • C语言中static关键字用法和作用

    static修饰的对象 xff1a static关键字可以修饰 xff1a 局部变量 全局变量 函数 static修饰后改变了什么 xff1f 1 改变了生存周期 xff1b 就是一个变量 函数从分配内存去表示到回收内存的过程 2 改变了作
  • c语言中NULL到底是什么?

    C语言中NULL到底是什么 xff1f 1 NULL在C C 43 43 中定义为 xff1a ifdef cplusplus 定义这个符号就表示当前是C 43 43 环境 define NULL 0 在C 43 43 中NULL就是0 e
  • register关键字详解

    前言 xff1a 编译器的优化很大程度上就是通过数据流分析 调整读取内存的顺序等 xff0c 减少CPU对内存的读写 因为内存的运行速度相对于CPU是很慢的 xff0c 计算机中添加cache就是为了解决CPU和内存运行速度差异过大的问题
  • 海思烧录工具HiTool的使用方法以及烧录uboot

    1 什么是HiTool HiTool是海思公司提供的用于海思芯片的烧录工具 xff0c 可用于烧录uboot kernel rootfs等 这里只是简单的介绍用HiTool通过串口去烧写uboot xff0c 更加仔细的使用方法可以参考海思
  • /etc/profile文件简单介绍

    什么是 etc profile文件 etc profile文件为系统的每个用户设置环境变量信息 此文件的修改会影响到所有用户 想了解更多细节内容可以用 xff1a vi etc profile 命令进行查看 etc profile文件和 b
  • 五月再不跳槽,就晚了

    从时间节点上来看 xff0c 3月 4月是每年跳槽的黄金季 xff01 之后的五月也会放出一些岗位 以 BAT 为代表的互联网大厂 xff0c 无论是薪资待遇 还是平台和福利 xff0c 都一直是求职者眼中的香饽饽 xff0c 大厂经历 在
  • I2C通信协议详解和通信流程分析

    1 I2C通信特征 1 1 物理接口 xff1a SCL 43 SDA 1 SCL serial clock xff1a 时钟线 xff0c 传输CLK信号 xff0c 一般是I2C主设备向从设备提供时钟的通道 2 SDA serial d
  • 用LED驱动框架注册led设备的示例代码

    1 LED驱动框架分析 参考博客 xff1a 内核LED驱动框架讲解以及led设备注册示例代码 xff1b 2 简单的用LED驱动框架注册led设备的代码 span class token macro property span class
  • 【C++入门】静态成员详解(定义、实现原理、使用注意事项)

    1 类的静态成员 1 在类中用static修饰成员 xff0c 则该成员是静态成员 xff1b 2 静态成员是属于类本身的 xff0c 所有类的对象共享 xff1b 3 类的对象都可以访问静态成员 xff0c 但是所有类的成员访问的静态成员
  • pci总线协议学习笔记——PCI总线基本概念

    1 pci总线概述 1 PCI xff0c 外设组件互连标准 Peripheral Component Interconnection xff0c 是一种由英特尔 xff08 Intel xff09 公司1991年推出的用于定义局部总线的标
  • RK3568芯片开发笔记——调试pwm控制红外功能

    1 PWM介绍 参考博客 xff1a ARM芯片开发 xff08 S5PV210芯片 xff09 定时器 看门狗 RTC xff1b 2 配置pwm功能的方法 1 内核层 xff1a 内核代码里有pwm子系统 xff0c 里面有pwm相关函

随机推荐

  • 海思芯片(hi3536av100)启动模式选择

    1 支持多种模式可配置 1 支持BootRom启动 2 支持从 SPI NOR Flash 启动 3 支持从 SPI NAND Flash 启动 4 支持从 eMMC 启动 5 支持 PCIe 从片启动 2 启动方式的选择 BOOT SEL
  • C语言头文件详解

    1 include的作用 简单一句话 xff1a 在include的地方 xff0c 把头文件里的内容原封不动的复制到引用该头文件的地方 2 头文件的引用 头文件引用有两种形式 xff1a include lt stdio h gt 和 i
  • wps云文档 wps自动备份怎么设置和取消

    转载请说明来源于 34 厦门SEO 34 本文地址 xff1a http www 96096 cc Article 169633 html wps云文档 WPS 为用户提供了自动备份的功能 xff0c 这为用户带来了方便的同时也给用户带来了
  • IDEA中Spring的配置使用

    IDEA中Spring的配置使用 1 首先创建JavaEE Web Application项目 xff0c 勾选Spring xff0c Libraries选择Set up library later xff08 有spring jar包的
  • content-type类型总结

    content type content type是http请求的响应头和请求头的字段 当作为响应头时 xff0c 告诉客户端实际返回的内容的内容类型 作为请求头时 xff0c 客户端告诉服务器实际发送的数据类型 前端开发过程中 xff0c
  • 外包干了6年,寄了

    前两天有读者想我资讯 xff1a 我是一名Android工程师 xff0c 工作已经四年多快五年了 现在正在找工作 xff0c 由于一直做的都是外包的项目 技术方面都不是很深入 xff0c 现在找工作都是会问一些 xff0c 四大组件 xf
  • java.lang.RuntimeException: Unable to instantiate activity ComponentInfo(不能实例化)异常解决

    java lang RuntimeException Unable to instantiate activity ComponentInfo xff08 不能实例化 xff09 异常解决 一 可能出现的原因及解决方法 xff1a xff0
  • Error:java: Compilation failed: internal java compiler error 的解决过程

    1 错误描述 xff1a IDEA导入一个新的项目 xff0c 运行时包编译失败 2 错误原因 这个错误的原因是因为 JDK 版本问题 xff0c 有两个原因 xff0c 一个是编译器版本不匹配 xff0c 一个是当前项目 JDK 版本不支
  • SpringCloud-21-Hystrix全局降级和解耦降级逻辑

    8 6 全局降级方法 通过上面的方式实现服务降级时 xff0c 需要针对所有业务方法都配置降级方法 xff0c 这极有可能会造成代码的急剧膨胀 为了解决该问题 xff0c 我们还可以为所有业务方法指定一个全局的回退方法 xff0c 具体步骤
  • Linux学习-61-Linux系统服务管理

    14 Linux系统服务管理 系统服务 xff1a 服务是在后台运行的应用程序 xff0c 并且可以提供一些本地系统或网络的功能 Linux 中常见的服务有那些 xff0c 这些服务怎么分类 xff0c 服务如何启动 xff0c 服务如何自
  • Linux学习-84-安装PHP

    17 13 安装PHP PHP xff08 PHP xff1a Hypertext Preprocessor递归缩写 xff09 中文名字是 xff1a 超文本预处理器 xff0c 是一种广泛使用的通用开源脚本语言 xff0c 适合于Web
  • redis学习-33-SpringBoot整合redis

    36 SpringBoot整合redis SpringBoot操作数据 xff1a 使用spring data项目 例如 xff1a jpa jdbc mongodb redis SpringData也是和SpringBoot齐名的项目 x
  • redis学习-34-PHP/Python使用Redis

    37 PHP使用Redis 首先需要熟练掌握 PHP 语言 xff0c 再者是已经安装了 PHP Redis 扩展程序 37 1 安装扩展程序 首先下载 PHP Redis 扩展程序 xff0c 下载的扩展程序要与 Redis 版本相符合
  • redis学习-35-Redis配置项汇总

    40 配置项汇总 对 Redis 的常用配置项和基本命令做简单的总结 xff0c 可以把本章看做简版的速查手册 不过 xff0c 需要注意的是由于 Redis 不同版本的差异 xff0c 配置项会多少存在一些不同 xff0c 但总体的来说
  • 韦东山:机会总是留给有准备的人(转)

    最近电子发烧友 xff08 以下称 39 发烧友 39 xff09 采访了韦东山老师 xff0c 本文是采访原稿 xff0c 展示出来让大家更深入了解韦老师的同时也进一步学习嵌入式Linux经验 机会总是留给有准备的人 发烧友 为什么要学习
  • matplotlib-animation--制作动画--制作各种图形-圆形矩形三角形

    目录 各个图形覆盖的问题 1 xff0c 画矩形并让其动起来 2 xff0c 画一个三角形 xff1a 动起来 xff01 3 xff0c 画一个三角形让其自动顺时针旋转 本教程基于前面的animation基础 xff0c 让各种图形动起来
  • 使用TS开发小程序中遇到的问题

    在使用ts开发小程序的过程中 xff0c 遇到了一些开发工具和关于ts的使用上的一些问题 xff0c 并记录解决方法 1 ts开发过程中类型指定问题 Type 39 number undefined 39 is not assignable
  • RecyclerView 使用总结以及常见问题解决方案

    1 RecycleView设置了数据不显示 本文主要讲一下我个人对于RecycleView的使用的一些思考以及一些常见的问题怎么解决 先来看一下使用RecycleView时常见的问题以及一些需求 这个往往是因为你没有设置LayoutMang
  • AidLearning中如何启动设置VNC和XFCE4

    第一步 xff1a 打开桌面的Service 第二步 xff1a 在Service Lists中选择中 Vncserver on port 5901 xff0c 点击启动 xff0c 点击保存 xff0c 保存服务后下次进入LECE4就会自
  • 自定义类加载器及其双亲委托机制

    自定义类加载器及其双亲委托机制 JAVA自带的类加载器自定义类加载器代码示例 双亲委托机制 JAVA自带的类加载器 JAVA的类加载器分为三种 xff0c 启动类加载器 系统类加载器 扩展类加载器以及系统类加载器 由前到后每一个都是下一个的