Java编程基础-类加载机制

news2024/9/24 1:21:33

文章目录

      • 基本概念
      • 类加载器的层次结构
      • 类的加载过程
      • 双亲委派模型
      • 自定义类加载器
      • 注意事项

Java 类加载器(Class Loader)是 Java 运行时环境的一部分,它负责在应用程序运行时加载类和接口的字节码。类加载器对于 Java 的动态特性和安全性有着至关重要的作用。下面将详细介绍 Java 类加载器的基本概念、层次结构以及类的加载过程。

基本概念

  • 类加载:指的是将类的 .class 文件中的二进制数据读入到内存中,然后对其数据进行校验、转换解析并生成方法区中的运行时数据结构,最后在堆区创建一个 java.lang.Class 对象的过程。

  • 类加载器分类
    在这里插入图片描述

    • 启动类加载器(Bootstrap ClassLoader):是最顶层的类加载器,负责加载 <JAVA_HOME>\lib 目录中的或者被 -Xbootclasspath 参数指定路径中的,并且能够被虚拟机识别的类(如 java.lang.Object)。此加载器无法被 Java 程序直接获取到。
    • 扩展类加载器(Extension ClassLoader):这个类加载器由 sun.misc.Launcher$ExtClassLoader 实现,它负责加载 <JAVA_HOME>\lib\ext 目录中的,或者被 -Djava.ext.dirs 系统变量所指定的路径中的所有类库。
    • 应用类加载器(Application ClassLoader):也称为系统类加载器,由 sun.misc.Launcher$AppClassLoader 实现。它负责加载用户类路径(ClassPath)上所指定的类。可以通过 ClassLoader.getSystemClassLoader() 获取到该类加载器。

类加载器的层次结构

Java 类加载器具有层次结构,每个类加载器都有一个父加载器。如果一个类加载器收到了加载类的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父类加载器去完成,每一层的类加载器都是基于这种“父母委托模型”来工作的。

类的加载过程

在这里插入图片描述

类的加载过程可以分为三个阶段:加载(Loading)、链接(Linking)和初始化(Initialization)。

  • 加载(Loading):通过类的全限定名获取定义此类的二进制流;将此二进制流所代表的静态存储结构转化为方法区中的运行时数据结构;在 Java 堆中生成一个代表这个类的 java.lang.Class 对象,作为方法区这些数据的访问入口。

  • 链接(Linking):验证(Verification),确保类文件的字节流包含的信息符合当前虚拟机的要求;准备(Preparation),为类变量分配内存并设置类变量初始值;解析(Resolution),将常量池内的符号引用替换为直接引用。

  • 初始化(Initialization):执行类构造器 <clinit>() 方法,对类变量赋予正确的初始值。

双亲委派模型

双亲委派模型要求除了顶层的 Bootstrap ClassLoader 之外,其余的类加载器都应该有自己的父类加载器。这里的类加载器之间的父子关系一般不会反映到它们所在的 Java 类的继承层次关系中,因为类加载器类层次中的“父类加载器”仅仅是一个命名上的习惯。

双亲委派模型保证了 Java 核心 API 包的唯一性,防止了用户自定义的类加载器加载这些核心类库。

自定义类加载器

在 Java 中,自定义类加载器是通过继承 java.lang.ClassLoader 类并重写其 findClass 方法来实现的。ClassLoader 是所有类加载器的基类,它提供了类加载器的基本功能和服务。自定义类加载器通常用于实现更灵活的类加载策略,比如从特定位置加载类,或是实现类的热更新等需求。

下面是一个简单的自定义类加载器示例,展示如何实现基本的类加载逻辑:

import java.io.InputStream;
import java.io.ByteArrayOutputStream;

public class CustomClassLoader extends ClassLoader {
    private String classPath;

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

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        String path = name.replaceAll("\\.", "/");
        InputStream is = getClass().getResourceAsStream(classPath + "/" + path + ".class");
        if (is == null) {
            throw new ClassNotFoundException("Class not found: " + name);
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int bytesRead;
        try {
            while ((bytesRead = is.read(buffer)) != -1) {
                baos.write(buffer, 0, bytesRead);
            }
            is.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        byte[] b = baos.toByteArray();
        return defineClass(name, b, 0, b.length);
    }
}

在这个例子中,CustomClassLoader 继承自 ClassLoader,并且重写了 findClass 方法。当 JVM 请求 CustomClassLoader 加载一个类时,它会查找类文件并将其转换为字节数组,然后使用 defineClass 方法将这些字节定义成一个 Class 对象。

为了使用这个自定义类加载器,你需要实例化它,并使用它的 loadClass 方法来加载类,如下所示:

public class Main {
    public static void main(String[] args) throws Exception {
        CustomClassLoader loader = new CustomClassLoader("/path/to/classes");
        Class<?> myClass = loader.loadClass("com.example.MyClass");
        Object instance = myClass.newInstance();
        // 使用 instance 进行进一步的操作
    }
}

在这个例子中,/path/to/classes 是你的类文件所在目录的路径,com.example.MyClass 是你要加载的类的完全限定名。

注意事项

  • 类加载器隔离性:每个类加载器加载的类都与其他类加载器加载的同名类相互独立,这意味着即使两个类加载器加载相同的类文件,这两个类在 JVM 中也被视为不同的类。
  • 资源定位:自定义类加载器需要正确地定位类文件的位置,并且要处理好类路径的问题。
  • 安全性和权限:自定义类加载器可能会涉及到安全性和权限的问题,例如,某些操作可能需要特定的安全管理器权限。

通过自定义类加载器,你可以实现许多高级特性,如代码热插拔、模块化加载、安全沙箱等。然而,编写自定义类加载器需要仔细考虑与 JVM 类加载机制相关的各种细节,包括类加载顺序、类的可见性以及安全性等问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2099682.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Microsoft DirectML 现在支持 Copilot+ PC 和 WebNN

DirectML 是一个底层应用程序接口&#xff0c;使开发人员能够在任何兼容 DirectX 12 的 AMD、英特尔和英伟达&#xff08;NVIDIA&#xff09;GPU 上运行机器学习工作负载 。它首次出现在Windows 10 的 1903 版本中。最近&#xff0c;微软 开始在 DirectML 中支持现代 SoC 中的N…

新能源汽车超级电容和电池能量管理系统的simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 电池模型 4.2 电池荷电状态&#xff08;SOC&#xff09;估算 4.3 超级电容器模型 4.4 能量管理 5.完整工程文件 1.课题概述 新能源汽车的能量管理系统&#xff08;Energy Management System, EMS…

Conda离线部署django

要在没有网络连接的环境中使用conda部署Django&#xff0c;你需要预先在有网络连接的机器上创建一个包含所有必要包的环境&#xff0c;并导出该环境的配置文件。然后&#xff0c;你可以将这个配置文件和必要的包传输到目标机器上进行安装。 下面是详细的步骤&#xff1a; 1. …

mysql优化案例分享

一、mysql介绍 1、InnoDB引擎 mysql5.5.8版本开始后。InnoDB引擎就是默认存储引擎&#xff0c;本文介绍知识点也都是围绕该引擎展开。 知识点1聚集存储 InnoDB引擎采用聚集存储&#xff0c;即每张表的存储都是主键的顺序进行存放&#xff0c;也就是每行存储的物理顺序和主键…

基于SparkGraphX实现带权重的PageRank算法

基于SparkGraphX实现带权重的PageRank算法 文章目录 基于SparkGraphX实现带权重的PageRank算法一、什么是PageRank算法二、PageRank算法的实现三、PagRank算法实现步骤四、大数据量的PageRank算法实现总结 一、什么是PageRank算法 网页排序算法之PageRank 二、PageRank算法的…

【AI视频】Runway注册、基本设置、主界面详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI视频 | Runway 文章目录 &#x1f4af;前言&#x1f4af;Runway的正确启动方式推荐使用Google Chrome打开Chrome翻译 &#x1f4af;Runway的注册&#x1f4af;My Account&#xff08;我的账户&#xff09;General&#xff08;常…

HTTPie CLI:重塑命令行HTTP交互的现代工具

更多内容前往个人网站&#xff1a;孔乙己大叔 在快速发展的数字时代&#xff0c;API&#xff08;应用程序编程接口&#xff09;已成为连接不同服务和应用的桥梁。无论是开发者还是系统管理员&#xff0c;与HTTP服务进行有效且高效的交互都是日常工作的核心部分。然而&#xff0…

idea中git提交或push到远程后回退到之前的某次提交简单有效的解决方案

场景&#xff1a; 1、先模拟出团队多人开发多分支&#xff0c;在各个分支分别提交代码&#xff0c;然后都合并到master分支 2、模拟如下两个分支dev、dev-0902合并到master&#xff0c;并且合并master后push到远程了 3、假如更新版本计划有变&#xff0c;只上dev-0902分支&…

stm32之I2C通信外设

系列文章目录 1. stm32之I2C通信协议 2. stm32之软件I2C读写MPU6050陀螺仪、加速度传感器应用案例 3. stm32之硬件I2C读写MPU6050陀螺仪、加速度传感器应用案例 文章目录 系列文章目录前言一、I2C通信外设1.1 I2C外设简介1.2 软件模拟和硬件外设对比 二、I2C外设电路结构2.1 I…

【数据结构-二维前缀异或和】【分区算法优化】力扣1738. 找出第 K 大的异或坐标值

给你一个二维矩阵 matrix 和一个整数 k &#xff0c;矩阵大小为 m x n 由非负整数组成。 矩阵中坐标 (a, b) 的 目标值 可以通过对所有元素 matrix[i][j] 执行异或运算得到&#xff0c;其中 i 和 j 满足 0 < i < a < m 且 0 < j < b < n&#xff08;下标从 …

IP网络广播系统(IP网络广播系统是什么及它的优势与应用)

一、引言 在当今数字化的时代&#xff0c;音频传播技术也在不断革新。IP网络广播系统作为一种先进的音频传输解决方案&#xff0c;正逐渐在各个领域发挥重要作用。那么&#xff0c;究竟什么是IP网络广播系统呢&#xff1f;它又有着怎样独特的优势和广泛的应用呢&#xff1f;本…

1、Django Admin学习模型

此专栏应用环境和模型基于此文 开发环境 系统&#xff1a;windows11 开发工具&#xff1a;vscode 开发语言&#xff1a;python 3.8 开发框架&#xff1a;django 3.2 数据库&#xff1a;mysql8.4.1 项目目录 settings 注册两个应用 INSTALLED_APPS [django.contrib.ad…

免下载看视频,使用极空间部署P2P磁力种子流媒体服务器『TorrServer』

免下载看视频&#xff0c;使用极空间部署P2P磁力种子流媒体服务器『TorrServer』 哈喽小伙伴们好&#xff0c;我是Stark-C~ 说到在NAS上的观影体验&#xff0c;很多小伙伴的理解可能就是先下载到本地&#xff0c;然后在使用播放器打开观看。今天为大家分享另外一种观影方式&a…

JS设计模式之“语言之魂” - 原型模式

前言 当我们学习JavaScript的时候&#xff0c;经常会听到原型&#xff08;prototype)、原型链&#xff08;prototype chain&#xff09;和原型模式&#xff08;prototype pattern&#xff09;这些概念&#xff0c;它们之间有什么关联呢&#xff1f;怎么样才能使用好原型模式呢…

linux 硬件 arm架构

一.ARM&#xff1a; 1.时钟晶振&#xff1a; 在单片机系统里晶振的作用非常大&#xff0c;他结合单片机内部的电路&#xff0c;产生单片机所必须的时钟频率&#xff0c;单片机的一切指令的执行都是建立在这个基础上的&#xff0c;晶振的提供的时钟频率越高&#xff0c;那单片机…

Valley14.2免授权php跨境电商在线商城

6Valley 14.2 Nulled – 多供应商电子商务 – 完整的电子商务移动应用程序、Web、卖家和管理面板 后台可自定义收款&#xff0c;和翻译多国语言&#xff0c;中文需要自己对比翻译&#xff01;一般用不到中文。毕竟是跨境电商平台 带商家即时通讯&#xff0c;全套带文档和APP双端…

DReg-NeRF: Deep Registration for Neural Radiance Fields论文解读

目录 一、导言 二、NeRF2NeRF 三、相关工作 1、神经辐射场 2、点云配准 3、NeRF配准 四、DReg-NeRF 1、NeRF神经辐射场查询 2、特征提取 3、transformer 4、Decoder 五、损失函数 一、导言 该论文来自于ICCV2023&#xff0c;主要提到一种DReg-NeRF的配准方法&#…

SQL 数据查询

文章目录 3.4.1 单表查询定义特点单表无条件查询单表带条件查询对查询结果进行排序限制查询结果数量 3.4.2 分组查询定义特点&#xff1a;聚集函数GROUP BY短语HAVING子句分组查询小结 3.4.3 连接查询定义特点&#xff1a;等值连接与非等值连接查询自然连接&#xff08;内连接&…

全局安装react

1、首先安装react脚手架 npm install -g create-react-app2、创建react项目 create-react-app my-app3、 PS D:\桌面\papers\subject> create-react-app my-react-appCreating a new React app in D:\桌面\papers\subject\my-react-app.Installing packages. This might …

基于vue框架的超市订单管理系统16uob(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;员工,商品分类,商品信息,供货商,入库订单,销售订单,货架信息,盈利信息 开题报告内容 基于Vue框架的超市订单管理系统开题报告 一、研究背景与意义 随着信息技术的飞速发展和电子商务的普及&#xff0c;传统超市管理模式正面临前所未有…