JVM双亲委派模型
在之前的JVM类加载器篇中说过,各个类加载器都有自己加载的范围,比如引导类加载器只加载Java核心库中的class如String,那如果用户自己建一个包名和类名与String相同的类,会不会被引导类加载器加载。可以通过如下代码测试,通过执行结果中的报错信息可以发现,JVM实际上加载了rt.jar中的String类,并未加载自定义的String,这个就是JVM的双亲委派模型解决的问题之一。
package java.lang;public class String {static {System.out.println("自定义String");}public static void main(String[] args) {System.out.println("1");}
}
运行结果
错误: 在类 java.lang.String 中找不到 main 方法, 请将 main 方法定义为:public static void main(String[] args)
否则 JavaFX 应用程序类必须扩展javafx.application.Application
双亲委派工作原理
JVM对class文件是按需加载,在加载class的过程,如果当前类加载器存在父类加载器,都会将加载请求先委派给父类加载器,这种任务委派方式被称为双亲委派。
在前面的篇章中说过,类加载器之间存在非继承的层次关系(如下图),这种层次关系让类加载器加载的类也具有优先级,也就是前面示例中rt.jar中的String优于自定义String的加载,这种优先级加载详细原理如下:

- 当一个类加载器收到加载请求,他并不会自己加载,而是把加载请求委托给父类加载器。
- 如果父类加载器也存在父类加载器,继续向上委托,如此递归,直至最顶层引导类加载器。
- 如果父类加载器能完成类的加载,就正常返回,反之,由子类进行加载,递归依次向下。
优点
1、避免全限定名相同的类被重复加载,导致程序异常。
2、保护程序,防止核心库API被篡改。
三、Java源码实现
双亲委派是在ClassLoader的loadClass()方法中实现,代码很少,作用很强大,源码如下。
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass<?> 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 statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}
}
SPI机制打破双亲委派
SPI(Service Provider Interface),是一种服务发现机制,它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类,如JDBC驱动。如下图,SPI核心类定义在rt.jar中(如java.lang.Driver接口),所以本身是由启动类加载器加载,当调用SPI接口的实现类时,启动类加载器是无法加载实现类的,这个时候就提供了线程上下文类加载器(Thread Context ClassLoader)加载实现类,ThreadContextClassLoader是可以通过java.lang.Thread#setContextClassLoader方法设置,如果没有设置默认为ApplicationClassLoader,这样双亲委派模型中ApplicationClassLoader->BootStrapClassLoader的委派,变成了BootStrapClassLoader->ApplicationClassLoader的委派,这样就打破了双亲委派的类加载模式。

相关文章:
JVM双亲委派模型
在之前的JVM类加载器篇中说过,各个类加载器都有自己加载的范围,比如引导类加载器只加载Java核心库中的class如String,那如果用户自己建一个包名和类名与String相同的类,会不会被引导类加载器加载。可以通过如下代码测试࿰…...
Python语言与算法:深度探索与实战应用
Python语言与算法:深度探索与实战应用 在数字化浪潮汹涌的时代,Python语言以其简洁、易读和强大的功能库成为了编程界的翘楚。而算法,作为计算机科学的核心,是解决问题、优化性能的关键。本文将围绕Python语言与算法的结合&#…...
Python实现连连看7
3.3 根据地图显示图片 在获取了图片地图之后,就可以根据该图片地图显示图片了。显示图片的功能在自定义函数drawMap()中实现。 3.3.1 清除画布中的内容 在画布上显示图片之前,需要将画布中图1的启动界面内容清除,代码如下所示。 canvas.delete(all) 其中,delete()方法…...
C#中的as和is
在 C# 中,as 和 is 是用于类型转换和类型检查的操作符。 as 操作符: as 操作符用于尝试将一个对象转换为指定的引用类型或可空类型,如果转换失败,将返回 null。语法:expression as type示例: object obj &…...
示波器眼图怎么看
目录 什么是眼图? 怎么看? 眼图的电压幅度(Y轴) 眼睛幅度和高度 信噪比 抖动 上升时间和下降时间 眼宽 什么是眼图? 眼图(Eye Diagram)是一种用于分析高速数字信号传输质量的重要工具。通…...
Visual Studio Code编辑STM32CubeMX已生成的文件
在这里插入图片描述...
【读脑仪game】
读脑仪(Brain-Computer Interface,BCI)游戏是一种利用脑电信号来控制游戏的新型交互方式。这类游戏通常需要专业的硬件设备来读取用户的脑电信号,并将这些信号转化为游戏中的控制信号。编写这样的游戏代码涉及到多个方面ÿ…...
基于STM32的毕业设计示例
**基于STM32的毕业设计示例** 一、引言 在当前的电子工程领域,STM32微控制器因其高性能、低功耗和丰富的外设接口而备受青睐。本次毕业设计旨在展示基于STM32微控制器的系统设计与实现能力,通过构建一个具有实际应用价值的系统,体现对嵌入式…...
图片格式怎么转成pdf,简单的方法
在现代数字化时代,图片格式转换成PDF已经成为许多人的日常需求。无论是为了存档、分享还是打印,将图片转换为PDF都是一项非常实用的技能。本文将详细介绍如何将图片格式转换成PDF的方法。 用浏览器打开 "轻云处理pdf官网,上传图片。 图…...
在 Debian 上使用和配置 SSH 的指南
SSH(Secure Shell)是用于在不安全网络上安全登录远程计算机和执行命令的协议。本文将详细介绍如何在 Debian 系统上安装、配置和使用 SSH。 1. 安装 SSH 首先,您需要安装 OpenSSH 服务器和客户端(也可直接安装服务器端ÿ…...
Sleep | 纺锤波-慢波耦合与解决问题的能力:年龄的影响
摘要 本研究考察了衰老如何影响睡眠在巩固新学习的认知策略中的作用。共纳入40名健康年轻人(20-35岁)和30名健康老年人(60-85岁)。参与者接受了河内塔(ToH)任务的训练,然后,每个年龄组的一半参与者被分配到90分钟的午睡条件下,另一半则保持清…...
代码随想录 day 30
回溯总结: 相当于暴力for循环,其目的用递归控制for循环嵌套的数量。当剪枝时,就可以使得嵌套数量减少。把回溯问题抽象一颗树比较好懂。并且使得代码更简洁。 对于组合问题,什么时候需要startIndex呢? 在一个集合求组合…...
SD NAND(贴片式TF卡)坏块管理技术问答
Q1:什么是NAND的块(Block))? 每个Nand包含一个或多个Chip。Chip是可以独立执行命令并上报状态的最小单元。 每个Chip包含一个或多个plane。不同的plane间可以并发操作,不过有一些限制。 每个plane包含多block,block是最小擦除单元(擦除后为…...
学习使用js监测浏览器窗口大小变化
学习使用js监测浏览器窗口大小变化 在JavaScript中,可以通过监听resize事件来检测浏览器窗口的大小变化。以下是一个简单的示例代码,用于检测浏览器窗口大小的变化并在控制台输出新的窗口尺寸: javascript // 定义一个处理窗口大小变化的函数…...
微服务开发与实战Day02 - Docker
一、Docker快速入门 快速构建、运行、管理应用的工具 安装部署教程:Docs 1. 部署MySQL 测试连接: 镜像和容器 当我们利用Docker安装应用时,Docker会自动搜索并下载应用镜像(image)。镜像不仅包含应用本身ÿ…...
蒙层(css)
如何在 Vue 中实现一个包含图像和蒙层效果的组件?这个组件根据某个条件显示或隐藏蒙层,用于表示图像是否已读。 1. 创建基础模板 首先,我们在模板中使用 div 包裹我们的图像组件 GraphImage,并为最外层 div 设置 position: relat…...
SpringBoot前端URL访问本地磁盘文件
SpringBoot前端通过 URL访问本地磁盘文件,其实就是 SpringBoot访问web中的静态资源的处理方式。 SpringBoot 访问web中的静态资源:https://blog.csdn.net/qq_42402854/article/details/90295079 首先,我们知道浏览器访问本地磁盘文件的方式为…...
【WP】猿人学2_js混淆_动态cookie
https://match.yuanrenxue.cn/match/2 抓包分析 根据发包加密参数在cookie中 删除cookie带的m参数,重新点击其他页面,然后使用Fiddler抓包 第一个包请求没有携带m,但是后面的请求是附带了m了,所以m就是在此之间生成 查看不带…...
基于springboot实现民族婚纱预定系统项目【项目源码+论文说明】
基于springboot实现民族婚纱预定系统的设计演示 摘要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本民族婚纱预定系统就是在这样的大环境下诞生,其可…...
String常用操作
String常用方法 构造字符串 常用的构造字符串有3种: 1.直接赋值String s "abcd"; 2.实例化调用构造方法String s new String("abcd"); 3.实例化传字符数组 char[] ch {a,b,c,d}; String s new String(ch);字符串比较 比较 比较的是两个…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
