类加载以及类加载器

Java基础之类加载器 由上文中的流程图可以看出,类加载器负责读取Java字节代码(.class文件),并转换成java.lang.Class类的一个实例。每个这样的实例用来表示一个Java类。通过此实例的newInstance()方法就可以创建出该类的一个对象。实际的情况可能更加复杂,比如Java字节代码可能是通过工具动态生成的,也可能是通过网络下载的。oracle官网把类加载器划分为两种类型java库中的平台类加载器和应用程序类加载器等用户自己写的类加载器,比如通过网络加载类等机制举例。... 阅读详情
  • 什么是类加载?

将类的.class文件中的二进制数据读入到JVM中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的java.lang.Class对象,用来封装类在方法区类的对象

  • 类加载的步骤

加载、验证、准备、解析、初始化、使用、卸载;下面分别介绍这几步:

加载:在硬盘上查找并通过IO读入字节码文件,使用到类时才会加载,例如调用类的
main()方法,new对象等等,在加载阶段会在内存中生成一个代表这个类的
java.lang.Class对象,作为方法区这个类的各种数据的访问入口

关于方法区的简单介绍:

类被加载到方法区中后主要包含 运行时常量池、类型信息、字段信息、方法信息、类加载器的
引用、对应class实例的引用等信息。
类加载器的引用:这个类到类加载器实例的引用
对应class实例的引用:类加载器在加载类信息放到方法区中后,会创建一个对应的Class 类型的
对象实例放到堆(Heap)中, 作为开发人员访问方法区中类定义的入口和切入点。

验证:校验字节码文件的正确性

准备:给类的静态变量分配内存,并赋予默认值

解析:将符号引用替换为直接引用。   (该阶段会把一些静态方法(符号引用,比如
main()方法)替换为指向数据所存内存的指针或句柄等(直接引用),这是所谓的静态链接过
程(类加载期间完成),动态链接是在程序运行期间完成的将符号引用替换为直接引用,下
节课会讲到动态链接)

初始化:对类的静态变量初始化为指定的值,执行静态代码。

  • 类加载器

java中有四种类加载器:

1)BootstrapClassLoader(启动类加载器)
  负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar、charsets.jar等
2)ExtensionClassLoader(标准扩展类加载器)
        负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包  
3)AppClassLoader(系统类加载器)
        负责加载ClassPath路径下的类包,主要就是加载你自己写的那些类
4)CustomClassLoader(自定义加载器)
  属于应用程序根据自身需要自定义的ClassLoader,如tomcat

通过以下代码可以查看不同类加载器加载的路径:

public class TestJDKClassLoader {

    public static void main(String[] args) {
        ClassLoader appClassLoader = ClassLoader.getSystemClassLoader();
        ClassLoader extClassloader = appClassLoader.getParent();
        ClassLoader bootstrapLoader = extClassloader.getParent();
        System.out.println("the bootstrapLoader : " + bootstrapLoader);
        System.out.println("the extClassloader : " + extClassloader);
        System.out.println("the appClassLoader : " + appClassLoader);

        System.out.println();
        System.out.println("bootstrapLoader加载以下文件:");
//        URL[] urls = Launcher.getBootstrapClassPath().getURLs();
//        for (int i = 0; i < urls.length; i++) {
//            System.out.println(urls[i]);
//        }

        System.out.println(System.getProperty("sun.boot.class.path"));

        System.out.println();
        System.out.println("extClassloader加载以下文件:");
        System.out.println(System.getProperty("java.ext.dirs"));

        System.out.println();
        System.out.println("appClassLoader加载以下文件:");
        System.out.println(System.getProperty("java.class.path"));
    }
}
  • 双亲委派机制

加载某个类时会先委托父加载器寻找目标类,找不到再委托上层父加载器加载,直至引导类加载器后再逐层往下找,如果所有父加载器在自己的加载类路径下都找不到目标类,则在自己的类加载路径中查找并载入目标类

双亲委派机制的核心源码:AppClassLoader的loadClass方法最终会调用其父类ClassLoader的loadClass()

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;
        }
    }

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

  • 双亲委派机制的意义

沙箱安全机制:自己写的java.lang.String.class类不会被加载,这样便可以防止核心
API库被随意篡改;

避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一
次,保证被加载类的唯一性

全盘委托机制

“全盘负责”是指当一个ClassLoader装载一个类时,除非显示地使用另一个ClassLoader,则该类所依赖及引用的类也由这个CladdLoader载入。

打破双亲委派机制

自定义类加载器

核心:1、指定加载路径;重写findClass()

package com.tuling.designpattern.snail;

import java.io.FileInputStream;

public class MyClassLoaderTest {
    static class MyClassLoader extends ClassLoader {
        private String classPath;

        public MyClassLoader(String classPath) {
            this.classPath = classPath;
        }

        private byte[] loadByte(String name) throws Exception {
            name = name.replaceAll("\\.", "/");
            FileInputStream fis = new FileInputStream(classPath + "/" + name
                    + ".class");
            int len = fis.available();
            byte[] data = new byte[len];
            fis.read(data);
            fis.close();
            return data;
        }
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            try {
                byte[] data = loadByte(name);
                //defineClass将一个字节数组转为Class对象,这个字节数组是class文件读取后最终的字节 数组。
                return defineClass(name, data, 0, data.length);
            } catch (Exception e) {
                e.printStackTrace();
                throw new ClassNotFoundException();
            }
        }

    }
}

打破

不交给父类加载,首先自己加载

模拟tomcat打破

  • 打破的必要性:

我们思考一下:Tomcat是个web容器, 那么它要解决什么问题:
1. 一个web容器可能需要部署两个应用程序,不同的应用程序可能会依赖同一个第三方类库的
不同版本,不能要求同一个类库在同一个服务器只有一份,因此要保证每个应用程序的类库都是
独立的,保证相互隔离。
2. 部署在同一个web容器中相同的类库相同的版本可以共享。否则,如果服务器有10个应用程
序,那么要有10份相同的类库加载进虚拟机。
3. web容器也有自己依赖的类库,不能与应用程序的类库混淆。基于安全考虑,应该让容器的
类库和程序的类库隔离开来。
4. web容器要支持jsp的修改,我们知道,jsp 文件最终也是要编译成class文件才能在虚拟机中
运行,但程序运行后修改jsp已经是司空见惯的事情, web容器需要支持 jsp 修改后不用重启。

  • 核心操作步骤(针对上述问题3):

自定义类加载器(本文代码已实现);

各个Webapp私有的类加载器,加载路径中的class只对当前
Webapp可见,比如加载war包里相关的类,每个war包应用都有自己的
WebappClassLoader,实现相互隔离,比如不同war包应用引入了不同的spring版本,
这样实现就能加载各自的spring版本;

其余问题

如何判断同一个类

注意:同一个JVM内,两个相同包名和类名的类对象可以共存,因为他们的类加载器可以不一
样,所以看两个类对象是否是同一个,除了看类的包名和类名是否都相同之外,还需要他们的类
加载器也是同一个才能认为他们是同一个。

ClassLoader中的parent属性在何处赋值的?

在源码中跟踪未发现。。。

JVM中类加载器分类与核心功能 1. 启动类加载器(Bootstrap ClassLoader):负责加载Java的核心类库,如rt.jar、resources.jar等。2. 扩展类加载器(Extension ClassLoader):负责加载JRE扩展目录(ext)中的jar包。3. 应用程序类加载器(Application ClassLoader):负责加载应用程序classpath目录下的类,也就是我们自己编写的Java类。下面分别以这三种类加载器为例,说明它们的核心功能以及如何使用它们加载类。 阅读详情

相关推荐

大白话讲解Numpy中什么是一维、二维、三维数组,以及5种创建方式

NumPy中提供了多种创建数组的方式,其中最基本的方式就是通过array()函数创建数组在使用该函数时直接传入列表或元组即可。 通过array()函数分别创建一维数组、二维组和三维数组,那么什么是维度呢?一维、二维、三维有什么区别? 1、什么是维度? 维度可以理解为描述数据的一种 “方向” 或者 “层次”。在数组中,维度的数量决定了我们需要用多少个索引来访问一个元素 2、一维、二维、三维的区别? (1)一维:一维数组就像是一条直线上排列的一组数据,例如: a = np.array([1, 2

1362

【Java 基础篇】Java类加载器详解

Java允许开发人员自定义类加载器,以满足特定的加载需求。自定义类加载器必须继承类,并重写findClass方法。在findClass方法中,开发人员可以根据自己的规则和逻辑来加载类的字节码。// 根据名称加载类的字节码 byte [ ] byteCode = loadClassByteCode(name);// 调用defineClass方法将字节码转换为Class对象 return defineClass(name , byteCode , 0 , byteCode . length);

繁依Fanyi的博客 1万+

Allegro17.4原理图-PCB双向联动技巧:从网表生成到同步高亮

本文深入解析了Cadence Allegro 17.4中原理图与PCB的深度双向联动技巧。核心在于通过精准的网表生成与管理、实时的跨窗口交互高亮与信号追踪,以及元件与封装的智能匹配更新,构建高效协同设计工作流。掌握这些技巧能显著提升高速、高密度电路设计的效率与准确性,实现从逻辑设计到物理实现的无缝衔接。

weixin_29178069的博客 358

JVM---类加载器

Java类加载器

靖妖傩舞 1494

西门子200SMART自定义库开发实战:从PID到露点算法的工业应用

本文详细介绍了西门子200SMART自定义库开发实战,涵盖从PID控制到露点算法的工业应用。通过代码封装技巧、多语言支持和性能优化等高级开发方法,帮助工程师提升PLC编程效率。文章特别强调了自创库在实际项目中的优势,如恒温恒湿控制系统的成功案例,展示了自定义库在工业自动化中的强大应用价值。

lake5的博客 1025

基于YOLOv8的玉米病害监测系统

本研究的主要目标是设计并实现一个基于深度学习的玉米病害识别系统,通过采用YOLOv8算法进行玉米叶片病害的自动化识别。研究首先对玉米病害的种类和特点进行了分析,选择了具有代表性的病害类型,如玉米锈病、灰叶斑病、枯叶病和健康叶片,以构建一个多类别的分类问题。数据集的构建和处理是研究的关键部分,通过数据增强、图像标注等手段确保了数据的多样性和丰富性,从而提高了模型的泛化能力。

yupan__的博客 496

深入理解Java虚拟机——再谈类的加载器——第十二章——中篇

文章目录1:概述1.1 类加载器分类1.2 类加载器的必要性1.3 命名空间1.4 类加载器的基本特性2:类的加载器分类2.1 引导类加载器2.2 扩展类加载器2.3 系统类加载器2.4 用户自定义类加载器3:测试不同的类加载器4:ClassLoader源码解析4.1 ClassLoader的主要方法4.2 SourceClassLoader与URLClassLoader4.3 ExtClassLoader和AppClassLoader4.4 Class.forName()与ClassLoader.load

qq_44891295的博客 1678

MATLAB与ROS联合仿真——订阅ROS消息类功能模块介绍

MATLAB与ROS联合仿真——订阅ROS消息类功能模块介绍 (1)输入参数:无 (2)输出参数:Xr和Yr是小车当前在世界坐标系下的坐标 (3)主要作用:作为ROS与MATLAB的通讯接口,从ROS中订阅小车当前的位置信息,并输出 (4)内部结构: (5)具体实现过程:通过ROS工具箱中的Subscribe模块从ROS中订阅话题/gazebo/link_statesa 通过Bus Selector模块选择ROS总线中的Pose

慕羽★的博客 2699

类加载器 超详解:什么是类加载器,类加载器作用及应用场景,类加载时机,类加载的完整过程,类加载器分类

类加载器 超详解:什么是类加载器,类加载器作用及应用场景,类加载时机,类加载的完整过程,类加载器分类

qq_44700578的博客 7084

4、风险管理、信息安全与信息管理的核心原则

本文深入探讨了风险管理、信息安全与信息管理的核心原则,涵盖Risk IT框架、ISO 31000标准以及信息安全与信息管理的关键原则。通过案例分析与实际应用挑战的解析,帮助组织更好地应对数字化时代的风险与安全问题,实现可持续发展。

bread的博客 120

【RT-DETR涨点改进】全网独家-特征融合改进篇 | AAAI 2025 顶会| 高效涨点,RT-DETR利用CDFA对比度特征聚合模块,适用于目标检查(全网独家创新)

本文提出了一种基于CDFA模块的多级特征融合优化RT-DETR模型,用于解决医学图像分割中的软边界模糊、小目标和共现现象等问题。CDFA模块通过对比度特征聚合、局部特征增强和多级注意力机制,有效提升模型性能。研究提供了三种改进方案(rtdetr-r18/y50/l-CDFA),并在多个医学数据集上验证了其有效性。核心创新包括语义信息解耦、对比驱动特征融合和尺寸感知解码器。实验结果表明,该方法在分割精度和鲁棒性方面达到SOTA水平。

Ai缝合怪、助力小伙伴高效发论文 509

Java_类加载器

对Java类加载器的讲解分析,包含程序段

AI+全栈,AI+应用,实操落地,前沿技术 2258

YOLOv11改进-上采样 | EUCB高效上卷积块,实现特征图尺度匹配和高效上采样

本文介绍了一种在YOLOv11目标检测模型中引入高效解码器模块EMCAD的创新方法,以提升模型在资源受限场景下的性能与效率。EMCAD由多个模块构成,其中核心的EUCB(高效上卷积块)通过上采样、深度可分离卷积、激活归一化和通道调整等操作,兼顾了特征质量与计算成本。实验结果显示,该模块在显著减少参数与FLOPs的同时仍具备优异性能。文章还提供了完整的YOLOv11模型集成流程、配置和训练实战。

魔改工程师的博客 1540

JVM类加载器

文章目录一、类加载器二、类与类加载器三、双亲委派模型四、破坏双亲委派模型4.1、Tomcat4.1.1、WebApp类加载器4.1.2、Shared类加载器4.1.3、Catalina类加载器4.1.4、Common类加载器4.1.5、Jsp类加载器4.2、JDBC 一、类加载器 从Java虚拟机的角度来讲,只存在两种不同的类加载器:一种是启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现,是虚拟机自身的一部分;另一种就是所有其他的类加载器,这些类加载器都由Java语

rockvine的博客 3485

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java类加载器及Android类加载器基础

引子Android插件化与热更新技术日渐成熟,当你研究这些技术时会发现类加载器在其中占据重要地位。Java语言天生就有灵活性、动态性,支持运行期间动态组装程序,而这一切的基础就是类加载器。Java中的类加载器Java灵活性和动态性的原因Java源代码被编译器编译成字节码,即从.java文件编译为.class文件,而.class文件就是通过类加载器加载到虚拟机内存中的。虚拟机的类加载(Class Lo

Battling against our own ignorance 3035

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

什么是类加载器,类加载器有哪些

类加载器(Class Loader)是Java虚拟机(JVM)的一部分,负责将Java类的二进制代码加载到内存中,并转换为可执行的Java字节码。它是Java语言的重要特性之一,为Java应用程序提供了动态加载和运行时扩展的能力。类加载器的主要职责是根据类的全限定名(Fully Qualified Name)在运行时定位并读取类的字节码。类加载器使用一种称为双亲委派模型(Parent Delegation Model)的机制来加载类。

Flying_Fish_roe的博客 2293

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

了解类加载器吗?类加载器的类型有哪些?

类加载器(ClassLoader)是JVM的核心组件,负责将.class文件加载到内存并生成Class对象。JVM内置三类加载器:Bootstrap(核心类库)、Extension(扩展类)、Application(应用类),支持自定义类加载器。类加载采用双亲委派机制,优先委派父加载器处理,确保核心类安全并避免重复加载。自定义类加载器通过继承ClassLoader实现,常用于热部署、插件系统等场景。线程上下文类加载器(如SPI)可突破双亲委派限制。理解类加载机制对Java模块化开发和安全部署至关重要。

笑衬人心的博客 1538

类加载器

类加载器(ClassLoader)是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术,类加载器只参与加载过程中的字节码获取并加载到内存这一部分。 类加载器虽然只用于实现类的加载动作,但它在Java程序中起到的作用却远超类加载阶段。对于任意一个类,都必须由加载它的类加载器和这个类本身一起共同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间。这句话可以表达得更通俗一些:比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来

m0_62943934的博客 1218

类加载器详解

类加载器从 JDK 1.0 就出现了,最初只是为了满足 Java Applet(已经被淘汰) 的需要。后来,慢慢成为 Java 程序中的一个重要组成部分,赋予了 Java 类可以被动态加载到 JVM 中并执行的能力。根据官方 API 文档的介绍:类加载器是一个负责加载类的对象。是一个抽象类。给定类的二进制名称,类加载器应尝试定位或生成构成类定义的数据。典型的策略是将名称转换为文件名,然后从文件系统中读取该名称的“类文件”。每个 Java 类都有一个引用指向加载它的。不过,数组类不是通过。

m0_74267125的博客 819

类加载器的作用

深入探讨 Java 类加载器 成 富, 软件工程师, IBM 中国软件开发中心 成富任职于 IBM 中国软件开发中心,目前在 Lotus 部门从事 IBM Mashup Center 的开发工作。他毕业于北京大学信息科学技术学院,获得计算机软件与理论专业硕士学位。他的个人网站是 http://www.cheng-fu.com。 简介: 类加载器(class loader)

zhouren1314的专栏 1944

Java 类加载器

类加载器可以说是Java语言的一项创新,让应用程序自己决定如何去获取所需的类的二进制字节流。

Happy博客 1065

Java中有哪些类加载器

在 Java 中,类加载器(ClassLoader)负责将类的字节码加载到 JVM 中,并生成对应的。

完全体 868

JVM——类加载器

讲解了JVM三种类加载器,即启动类加载器、扩展类加载器和应用程序类加载器,同时讲解了类加载器的源码,以及用户根据自己需求自定义类加载器,此外还介绍了它们之间的包含关系以及类加载器所采用的双亲委派机制。

码说芯语的博客 1562

Java的类加载器有哪些

职责:满足特定需求的类加载器,通常在应用程序中自定义实现。实现:继承java.lang.ClassLoader并重写findClass方法。加载路径:由开发者自行定义,可以是文件系统、网络、数据库等。父类加载器:可以指定,也可以继承应用程序类加载器。@Overridetry {// 将类名转换为文件路径// 读取类文件的字节码// 将字节码转换为 Class 对象当内置的三大类加载器无法满足需求时,就需要自定义类加载器。目的加载非 ClassPath 路径的类。

埃泽漫笔 1093

类加载器。

目录 一、类加载器 类加载器的作用: 1.启动类加载器 2.扩展类加载器 3.应用程序类加载器 二、操作实例 一、类加载器 类加载器的作用: 简单得说类加载器就是用于实现类的加载动作。 绝大多数Java程序都会使用到以下3个系统提供的类加载器来进行加载。 1.启动类加载器 这个类加载器负责加载存放在 \lib目录,或者被-Xbootclasspath参数所指定的路径中存放的,而且是Java虚拟机能够 识别的类库加载到虚拟机的内存中。启动类加载器无法被Java程...

欢迎一起学习交流 1337

什么是类加载器,类加载器如何分类

③ 在内存中生成一个代表这个类的java.lang.Class对象,任何类被使用时,系统都会为创建一个java.lang.Class对象,即加载完毕创建一个class对象。链接阶段的第一步,这一阶段为了确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机的自身安全,即文件中的信息是否符合虚拟机规范,有没有安全隐患。将类的二进制数据流中的符号引用替换为直接引用,即本类中如果用到了其他的类,此时就需要找到对应的类。类加载器:负责将.class文件(存储的物理文件)加载到内存中。

weixin_46665411的博客 2510
上一篇: linux常用命令
下一篇: JVM内存结构
Learning_foolish
博客等级 码龄9年 14粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值