双亲委派机制的作用


类加载过程

先简单说一下java的类加载器

类加载器,顾名思义就是一个可以将Java字节码加载为java.lang.Class实例的工具。这个过程包括,读取字节数组、验证、解析、初始化等。另外,它也可以加载资源,包括图像文件和配置文件。

类从被加载到内存中开始,到卸载出内存为止。它的生命周期总共七个阶段:加载---->验证---->准备---->解析---->初始化---->使用---->卸载。

1.加载(Loading):根据类的全限定名(包括包路径和类名),定位并读取类文件的字节码。

2.链接(Linking):将类的字节码转换为可以在虚拟机中运行的格式。链接过程包括三个阶段:

(1)验证(Verification):验证字节码的正确性和安全性,确保它符合Java虚拟机的规范。

(2)准备(Preparation):为类的静态变量分配内存,并设置默认的初始值。
(3)解析(Resolution):将类的符号引用(比如方法和字段的引用)解析为直接引用(内存地址)。

3.初始化(Initialization):执行类的初始化代码,包括静态变量的赋值和静态块的执行。

而在java中类是按需加载,(一个类只会被加载一次)

1、new创建对象

2、子类加载触发父类加载

3、调用静态成员

4、通过反射动态加载


一、java有哪些类加载器?

类加载器是Java虚拟机用于加载类文件的一种机制。在Java中,每个类都由类加载器加载,并在运行时被创建为一个Class对象。类加载器负责从文件系统、网络或其他来源中加载类的字节码,并将其转换为可执行的Java对象。类加载器还负责解析类的依赖关系,即加载所需的其他类。

Java虚拟机定义了三个主要的类加载器:

启动类加载器(Bootstrap Class Loader):也称为根类加载器,它负责加载Java虚拟机的核心类库,如java.lang.Object等。启动类加载器是虚拟机实现的一部分,它通常是由本地代码实现的,不是Java类。

扩展类加载器(Extension Class Loader):它是用来加载Java扩展类库的类加载器。扩展类库包括javax和java.util等包,它们位于jre/lib/ext目录下。

应用程序类加载器(Application Class Loader):也称为系统类加载器,它负责加载应用程序的类。它会搜索应用程序的类路径(包括用户定义的类路径和系统类路径),并加载类文件。

除了这三个主要的类加载器,Java还支持自定义类加载器,开发人员可以根据需要实现自己的类加载器。

如下是一个案例,代码中中parents和classLoader1 它的类加载器都是null,这是因为他们的类加载器都是Bootstrap Class Loader,而Bootstrap Class Loader是用C写的,在java无法识别。显示为null。

public class a {public static void main(String[] args) {// AppClassLoader@63947c6bClassLoader classLoader = a.class.getClassLoader();System.out.println("类a的classLoader:"+classLoader);// PlatformClassLoader@5f205aaClassLoader parent = classLoader.getParent();System.out.println("类a的父类classLoader:"+parent);// nullClassLoader parents = parent.getParent();System.out.println("类a的父类classLoader:"+parents);// nullClassLoader classLoader1 = String.class.getClassLoader();System.out.println("String字符串的classLoader:"+classLoader1);}
}类a的classLoader:jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
类a的父类classLoader:jdk.internal.loader.ClassLoaders$PlatformClassLoader@5f205aa
类a的父类classLoader:null
String字符串的classLoader:null

二、双亲委派机制

自定义String类

我自己定义了一个String的类,如果我创建了这个类。那么肯定是会打印123的。(该类在我的java.lang目录下)

package java.lang;/*** Description:**/
public class String {public String() {System.out.println("123");}
}

然后我又创建了一个A类,在这个main方法中new了一个String对象。

public class a {public static void main(String[] args) {java.lang.String a=new java.lang.String();System.out.println(a);}
}

按我们正常逻辑是不是会打印123,并且创建这个String对象。 但是结果并没有进行,创建的还是我们jdk中java.lang包下的String对象,而不是我们定义的String对象。 为什么会这样,这就涉及到我们的jvm的双亲委派机制了。

这是"java.lang"包下的ClassLoader类的底层源码。然后将代码翻到loaderClass()方法处:

 public Class<?> loadClass(String name) throws ClassNotFoundException {return loadClass(name, false);}//              -----??-----protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{// 首先,检查是否已经被类加载器加载过Class<?> c = findLoadedClass(name);if (c == null) {try {// 存在父加载器,递归的交由父加载器if (parent != null) {c = parent.loadClass(name, false);} else {// 直到最上面的Bootstrap类加载器c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// 如果仍然没有找到,则依次调用findClass方法// to find the class.c = findClass(name);}}return c;}

这段代码是这样的

当我们启动类加载器加载String对象时,它首先会去加载当前加载器的父类去加载,一直到Bootstrap Class Loader启动类加载器。

启动类加载器(Bootstrap Class Loader):负责加载包名为java、javax、sun等开头的类。

扩展类加载器(Extension Class Loader):负责加载位于jre/lib/ext目录下的类。

应用程序类加载器(Application Class Loader):一般类都由它来加载

在这里插入图片描述

这种设计有个好处是,如果有人想替换系统级别的类:String.java。篡改它的实现,在这种机制下这些系统的类已经被BootstrapClassLoader加载过了(为什么?因为当一个类需要加载的时候,最先去尝试加载的就是BootstrapClassLoader),所以其它类加载器并没有机会再去加载,从一定程度上防止了危险代码的植入。


总结

双亲委派的作用:

1.防止重复加载同一个.class:通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。

2.保证核心的.class不能被篡改:通过委托方式,不会去篡改核心.clsas,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Android AIDL] --- AIDL工程搭建

0 AIDL概念 AIDL&#xff08;Android Interface Definition Language&#xff09;是一种 IDL 语言&#xff0c;用于生成可以在 Android 设备上两个进程之间进行进程间通信&#xff08;IPC&#xff09;的代码。 通过 AIDL&#xff0c;可以在一个进程中获取另一个进程的数据和调…

尚硅谷大数据项目《在线教育之离线数仓》笔记006

视频地址&#xff1a;尚硅谷大数据项目《在线教育之离线数仓》_哔哩哔哩_bilibili 目录 第11章 数仓开发之ADS层 P087 P088 P089 P090 P091 P092 P093 P094 P095 P096 P097 P098 P099 P100 P101 P102 P103 P104 P105 P106 P107 P108 P109 P110 P111 …

Layer 2盛夏已至,StarkNet如何实现价值跃迁?

作者&#xff5c;Jason Jiang Layer 2概念在2023年夏天迎来爆发。Coinbase、ConsenSys等加密巨头纷纷下场&#xff0c;其部署的原生L2解决方案Base、Linea在过去两个月内相继完成主网上线&#xff1b;被誉为L2 四大天王之一的StarkNet也在夏天顺利完成“量子跃迁”升级&#x…

HDFS 架构剖析

目录 一、HDFS 架构整体概述 二、HDFS 集群角色介绍 2.1 整体概述 2.2 主角色&#xff1a;namenode 2.3 从角色&#xff1a;datanode 2.4 主角色辅助角色&#xff1a; secondarynamenode 三、HDFS 重要特性 3.1 主从架构 3.2 分块存储机制 3.3 副本机制 3.4 …

抖音视频删了怎么在电脑上找回来

【昨天整理电脑文件时&#xff0c;不小心将剪辑好的抖音作品误删了&#xff0c;但是回收站中找不回来了&#xff0c;这些视频是我花了很多心血制作的&#xff0c;如果没了真的十分可惜&#xff01;希望大家能帮帮我&#xff0c;告诉我应该如何恢复这些文件。】 现在人们都喜欢…

【日记】文章更新计划

有的时候博客内容会有变动&#xff0c;首发博客是最新的&#xff0c;其他博客地址可能会未同步,认准https://blog.zysicyj.top 更新日志 周更 【周一】 Kafka系列 【周二】 Nginx系列 【周三】 深入解读Redis系列 【周四】 设计模式系列 【周五】 深入理解MySQL系列 【周六】 微…

Java版本电子招标采购系统源码之传统采购模式面临的挑战

采购类型多 采购制度&#xff1a;采购金额、部门、品类的差异导致管理标准不同。 采购流程&#xff1a;从供应商管理、寻源操作到合同签订、订单执行&#xff0c;业务流程长&#xff0c;审批节点多&#xff0c;传统管理透明度低&#xff0c;联动性差。 供应商管理难 寻源&#…

华为OD机试 - TLV解析Ⅰ(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、Java算法源码五、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#xff09;》。 …

Pycharm配置及使用Git教程

文章目录 1. 安装PyCharm2. 安装Git3. 在PyCharm中配置Git插件4. 连接远程Gtilab仓库5. Clone项目代码6. 将本地文件提交到远程仓库6.1 git add6.2 git commit6.3 git push6.4 git pull 平时习惯在windows下开发&#xff0c;但是我们又需要实时将远方仓库的代码clone到本地&…

【OpenCV实战】4.OpenCV 五种滤波使用实战(均值、盒状、中值、高斯、双边)

OpenCV 五种滤波使用实战(均值、盒状、中值、高斯、双边&#xff09; 〇、Coding实战内容一、滤波、核和卷积1.1 滤波1.2 核 & 滤波器1.3 公式1.4 例子 二、图片边界填充实战2.1 解决问题2.2 相关OpenCV函数2.3 Code 三. 均值滤波实战3.1 理论3.2 Blur3.3 Code 四. 盒状滤波…

Unity资源无法下载 反复提示需同意Terms of Service和EULA 同意后无效的解决方案

前言 最近在玩Unity&#xff0c;跟着tutorial做点项目&#xff0c;但是在下载免费资源时&#xff0c;只有从网站上点“打开Unity”&#xff0c;才能在本地Unity Editor的Package Manager里找到这个资源&#xff08;且点一下下面的刷新就没有了&#xff09;&#xff0c;并且点击…

HTML 播放器效果

效果图 实现代码 <!DOCTYPE HTML> <html><head><title>爱看动漫社区 | 首页 </title><link href"css/bootstrap.css" relstylesheet typetext/css /><!-- jQuery --><script src"js/jquery-1.11.0.min.js"…