千家信息网

java类加载的双亲委派机制是什么

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇内容介绍了"java类加载的双亲委派机制是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一个
千家信息网最后更新 2026年10月31日java类加载的双亲委派机制是什么

本篇内容介绍了"java类加载的双亲委派机制是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一个编译后的class文件,想要在JVM中运行,就需要先加载到JVM中。java中将类的加载工具抽象为类加载器,而通过加载工具加载类文件的具体方式被称为双亲委派机制。

知识点

类加载器:通过一个类全限定名称来获取其二进制文件(.class)流的工具。

前述

首先明确一点,Java中类是描述一类对象的行为和状态,拥有封装、继承、多态特征。而类加载器这个对象在类结构上都是抽象类ClassLoader的子类

public abstract class ClassLoader {...}

根据具体功能不同,JDK提供了多个具体子类,例如:ExtClassLoader、AppClassLoader、URLClassLoader、MethodUtil等。

再明确一点,有了类加载功能,但还是考虑实际使用。例如,了解java的都知道java底层使用的是c++。也就是说C++也可以实现类加载文件,也可以说是文件加载功能。在实际使用中也是这么做的,那么这部分被加载的类的加载器如何在Java中描述呢?下面来描述

JDK实际采用的类加载方式,被称为双亲委派机制。其主要分类如下,这是一种抽象概念

  • Bootstrap ClassLoader

    • 系统类(rt.ar)的类加载器,采用C++代码加载

  • Extension ClassLoader

    • 扩展类(ext.jar)的类加载器,采用ExtClassLoader加载

  • Application ClassLoader

    • 用户类路径(classpath)上类的类加载器,采用AppClassLoader加载

  • 自定义类加载器

    • 自定义的类加载器,继承ClassLoader即可

双亲

既然称为双亲委派机制,则双亲是必须存在的。ClassLoader类存在一个parent属性。因此可以配置双亲。这个双亲是指ExtClassLoader和AppClassLoader,在JDK中则是这样设置:


ExtClassLoader.parent=null;

AppClassLoader.parent=ExtClassLoader

XXXClassLoader.parent=AppClassLoader

自定义的类加载器在构建时,如果未指定parent,则使用getSystemClassLoader()来获取父类加载器,而该方法默认获取的就是AppClassLoader。

以上的类加载方式,图示如下

委派

双亲设置之后,便可以委派了,委派过程也就是类文件加载过程,

protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException{    synchronized (getClassLoadingLock(name)) {        // 保证该类只加载一次        Class c = findLoadedClass(name);        if (c == null) {            long t0 = System.nanoTime();            try {                if (parent != null) {                    // 存在父级类加载器则使用父级的父级类加载器进行加载                    c = parent.loadClass(name, false);                } else {                    // 不存在父级类加载器则尝试使用BootstrapClassLoader进行加载                    c = findBootstrapClassOrNull(name);                }            } catch (ClassNotFoundException e) {                // 抛出类未找到异常说明父类加载器加载失败            }            if (c == null) {                // 父级类加载器未完成加载且BootstrapClassLoader也未完成加载则使用自己的加载方式                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;    }}

文字描述下这段代码:


加载类文件之前,先验证是否被加载过了,如果加载过就不再加载,防止被覆盖掉,也防止多次加载浪费资源。然后获取类加载器的parent

  • 如果parent不存在,则说明本身已经是ExtClassLoader了,则查询下类文件是否被Bootstrap ClassLoader加载过,找到就返回,否则返回null。

  • 如果parent存在,则让父类加载器去加载类文件,这个过程是往上递推的,如 parent->parent->parent

  • 以上流程处理完毕,如果发现返回的是null则说明已经递推到了Bootstrap ClassLoader且仍不能加载,则说明该类文件不符合所有的父类加载器的加载条件,于是便轮到自己来加载了。

上面说明中往上递推的过程就是委派了,而递推的方式是parent,于是就称为双亲委派机制。当然通俗理解是父类加载器优先加载模式。

后记

在委派流程,描述了在该类文件不符合所有的父类加载器的加载条件,于是便轮到自己来加载了。这里说明下加载条件

在Launcher指定了Bootstrap ClassLoader的加载文件夹System.getProperty("sun.boot.class.path");这个主要就是JDK指定的\lib\rt包

在ExtClassLoader中指定了加载文件夹:String var0 = System.getProperty("java.ext.dirs");这个主要就是JDK指定的\lib\ext包

在AppClassLoader中指定了加载文件夹:String var1 = System.getProperty("java.class.path");都是环境变量,自行可配。这个主要指的是开发中的类路径

由于AppClassLoader与ExtClassLoader都继承了URLClassLoader因此都会进行加载条件判断,如果是自定义的则可以重写loadClass来绕过双亲委派。当然不论怎么重写,加载二进制流的方法会校验类文件不能是加载以java开头的包中的类,这个是绕不过去的。

自定义类加载器示例

代码

public class ConsumerClassLoaderDemo extends ClassLoader {    public static void main(String[] args) throws Exception {        ClassLoader myClassLoader = new ConsumerClassLoader();        Object obj = myClassLoader.loadClass("cn.tinyice.demo.classloader.ConsumerClassLoaderDemo").newInstance();        ClassLoader classLoader = obj.getClass().getClassLoader();        // BootStrapClassLoader在Java中不存在的,因此会是null        while (null != classLoader) {            System.out.println(classLoader);            classLoader = classLoader.getParent();        }    }}class ConsumerClassLoader extends ClassLoader {    @Override    public Class loadClass(String name) throws ClassNotFoundException {        try {            String classFile = name.substring(name.lastIndexOf(".") + 1) + ".class";            InputStream in = getClass().getResourceAsStream(classFile);            if (null == in) {                return super.loadClass(name);            }            byte[] bytes = new byte[in.available()];            in.read(bytes);            return defineClass(name, bytes, 0, bytes.length);        } catch (IOException e) {            throw new ClassNotFoundException(name);        }    }}


控制台

cn.tinyice.demo.classloader.ConsumerClassLoader@12133b1sun.misc.Launcher$AppClassLoader@b4aac2sun.misc.Launcher$ExtClassLoader@f49f1cProcess finished with exit code 0

"java类加载的双亲委派机制是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

文件 双亲 委派 机制 方式 过程 实际 就是 条件 代码 功能 工具 文件夹 知识 中指 也就是 二进制 内容 子类 对象 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 华服互联网科技怎么样 互联网佳科技有限公司 互联网科技巨头监管 互联网通讯科技 紫鲸互联网科技 广州宏创互联网科技 凡科互联网科技 上海电发互联网科技有限公司 安控科技rtu产品工业互联网 互联网科技教育视频 互联网金融科技公司干啥的 中化能源互联网科技招聘 晓花互联网科技有限公司网址 互联网科技人工智能实验室 朱啸虎曾投资哪些互联网科技企业 用友工业互联网科技发展 广州有谷有贝互联网科技有限公司 西安有哪些互联网高科技企业 上海旺乐尼互联网科技有限公司 互联网科技快速发展优美句子 互联网科技股 天津市摩尔互联网科技 科技赋能下的互联网金融 广西拼得多互联网科技有限公司 海南科技产业互联网平台 允成互联网科技有限公司融资 工业互联网山东科技大学 郑州欣桑互联网科技有限公司 信承诺互联网科技有限公司 恒生科技指数 中概互联网
0