面试题:Java中的类加载器

1. 什么是类加载器,类加载器有哪些?

要想理解类加载器的话,务必要先清楚对于一个Java文件,它从编译到执行的整个过程

在这里插入图片描述

  • 类加载器:用于装载字节码文件(.class文件)
  • 运行时数据区:用于分配存储空间
  • 执行引擎:执行字节码文件或本地方法
  • 垃圾回收器:用于对JVM中的垃圾内容进行回收

类加载器

JVM只会运行二进制文件,而类加载器(ClassLoader)的主要作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来。现有的类加载器基本上都是java.lang.ClassLoader的子类,该类的只要职责就是用于将指定的类找到或生成对应的字节码文件,同时类加载器还会负责加载程序所需要的资源

类加载器种类

类加载器根据各自加载范围的不同,划分为四种类加载器:

  • 启动类加载器(BootStrap ClassLoader):

    该类并不继承ClassLoader类,其是由C++编写实现。用于加载JAVA_HOME/jre/lib目录下的类库。

  • 扩展类加载器(ExtClassLoader):

    该类是ClassLoader的子类,主要加载JAVA_HOME/jre/lib/ext目录中的类库。

  • 应用类加载器(AppClassLoader):

    该类是ClassLoader的子类,主要用于加载classPath下的类,也就是加载开发者自己编写的Java类。

  • 自定义类加载器:

    开发者自定义类继承ClassLoader,实现自定义类加载规则。

上述三种类加载器的层次结构如下如下:

在这里插入图片描述

类加载器的体系并不是“继承”体系,而是委派体系,类加载器首先会到自己的parent中查找类或者资源,如果找不到才会到自己本地查找。类加载器的委托行为动机是为了避免相同的类被加载多次

2. 什么是双亲委派模型?

如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就返回成功;只有父类加载器无法完成此加载任务时,才由下一级去加载。

在这里插入图片描述

3. JVM为什么采用双亲委派机制

(1)通过双亲委派机制可以避免某一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性

(2)为了安全,保证类库API不会被修改


Demo:在工程中新建java.lang包,接着在该包下新建String类,并定义main函数

public class String {public static void main(String[] args) {System.out.println("demo info");}
}

​ 此时执行main函数,会出现异常,在类 java.lang.String 中找不到 main 方法

在这里插入图片描述

​ 出现该信息是因为由双亲委派的机制,java.lang.String的在启动类加载器(Bootstrap classLoader)得到加载,因为在核心jre库中有其相同名字的类文件,但该类中并没有main方法。这样就能防止恶意篡改核心API库。

4. 说一下类装载的执行过程?

类从加载到虚拟机中开始,直到卸载为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中,验证、准备和解析这三个部分统称为连接(linking)

在这里插入图片描述

类加载过程详解

① 加载

在这里插入图片描述

  • 通过类的全名,获取类的二进制数据流。

  • 解析类的二进制数据流为方法区内的数据结构(Java类模型)

  • 创建 java.lang.Class 类的实例,表示该类型。作为方法区这个类的各种数据的访问入口

在这里插入图片描述

② 验证

在这里插入图片描述

验证类是否符合JVM规范,安全性检查

  • 文件格式验证:是否符合 Class 文件的规范
  • 元数据验证
    这个类是否有父类(除了Object这个类之外,其余的类都应该有父类)
    这个类是否继承(extends)了被final修饰过的类(被final修饰过的类表示类不能被继承)
    类中的字段、方法是否与父类产生矛盾。(被final修饰过的方法或字段是不能覆盖的)
  • 字节码验证
    主要的目的是通过对数据流和控制流的分析,确定程序语义是合法的、符合逻辑的
  • 符号引用验证:符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量

比如:int i = 3;
字面量:3
符号引用:i

③ 准备

在这里插入图片描述

为类变量分配内存并设置类变量初始值

  • static变量,分配空间在准备阶段完成(设置默认值)赋值在初始化阶段完成

  • static变量是final基本类型,以及字符串常量,值已确定,赋值在准备阶段完成

  • static变量是final引用类型,那么赋值也会在初始化阶段完成

public class Main
{static int b = 10;// 准备阶段赋默认值 0,初始化阶段赋值 10static final int c = 20;// 准备阶段赋值 20static final String d = "hello";// 准备阶段赋值 "hello" (常量)static final Object o = new Object();// 初始化阶段赋值
}

④ 解析

在这里插入图片描述

把类中的符号引用转换为直接引用

比如:方法中调用了其他方法,方法名可以理解为符号引用,而直接引用就是使用指针直接指向方法。

在这里插入图片描述

⑤ 初始化

在这里插入图片描述

对类的静态变量,静态代码块执行初始化操作

  • 如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。

  • 如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行。

⑥ 使用

在这里插入图片描述

JVM 开始从入口方法开始执行用户的程序代码

  • 调用静态类成员信息(比如:静态字段、静态方法)

  • 使用new关键字为其创建对象实例

⑦ 卸载

当用户程序代码执行完毕后,JVM 便开始销毁创建的 Class 对象,最后负责运行的 JVM 也退出内存

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

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

相关文章

零代码编程:用kimichat批量重命名txt文本文件

一个文件夹中有很多个txt文本文件,需要全部进行重命名。 可以在kimichat中输入提示词: 你是一个Python编程专家,要完成一个关于批量重命名txt文本文件的Python脚本,下面是具体步骤: D:\Best Seller Books 这个文件夹…

chatGPT中文在线版本(亲测可用

ChatGPT是一个先进的自然语言处理模型,由OpenAI开发。它通过深度学习技术训练而成,可以进行对话、回答问题等多种自然语言处理任务。对于学生、开发者、研究人员和任何对人工智能感兴趣的人来说,这是一个非常有用的工具。 最近找到一个国内可…

【算法篇】逐步理解动态规划1(斐波那契数列模型)

目录 斐波那契数列模型 1. 第N个泰波那契数 2.使用最小花费爬楼梯 3.解码方法 学过算法的应该知道,动态规划一直都是一个非常难的模块,无论是状态转移方程的定义还是dp表的填表,都非常难找到思路。在这个算法的支线专题中我会结合很多力…

html网页制作-3D旋转卡片

网页制作-3D旋转卡片 两种旋转卡片的制作 旋转卡片&#xff08;1&#xff09; 代码 html代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-wid…

遍历目录下的某个文件并删除

目录 需求 编写过程 演示 需求 大家在学习时可能会有一个自己的小目录&#xff0c;里面放着各种奇葩代码&#xff0c;有天突然发现&#xff0c;没有空间了&#xff0c;这时候发现遗留了很多的可执行文件&#xff0c;大大的浪费了我们的空间&#xff0c;但是由于层数深&#…

汽车ABS的bangbang控制和模糊PID控制

1、内容简介 略 82-可以交流、咨询、答疑 2、内容说明 摘要&#xff1a;本文旨在设计一种利用模糊控制理论优化的pid控制器&#xff0c;控制abs系统&#xff0c;达到对滑移率最佳控制范围的要求 &#xff0c;所提出的方案采用级联控制架构&#xff1a;设计用于外环中的车轮打…

第四百二十二回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"自定义标题栏"相关的内容&#xff0c;本章回中将介绍自定义Action菜单.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在这里提到的…

基于大数据的空气质量预测和可视化分析

城市空气质量数据采集系统设计与实现 &#x1f3d9;️ 研究背景 &#x1f32c;️ 城市化与环境挑战&#xff1a;随着城市化进程的加快&#xff0c;环境污染问题&#xff0c;尤其是空气质量问题&#xff0c;已成为公众关注的焦点。数据监测的重要性&#xff1a;城市空气质量数…

哪本书最了解孩子?跟《米小圈上学记》一起做孩子的“引路人”!

孩子是发展中的人&#xff0c;需要家长的陪伴&#xff0c;孩子的身心发展是有规侓的&#xff0c;是处于发展过程中的人。我们要学会尊重孩子的发展&#xff0c;从兴趣出发&#xff0c;关注孩子的成长。但是&#xff0c;家长不可能无时无刻都能陪在孩子身边&#xff0c;他需要一…

day06vue2学习

day06 路由的封装抽离 问题&#xff1a;所有的路由配置都堆在main.js中不太合适么&#xff1f;不好&#xff0c;会加大代码的复杂度 目标&#xff1a;将路由模块抽离出来。好处&#xff1a;差分模块&#xff0c;利于维护。 大致的做法就是&#xff0c;将路由相关的东西都提…

ChatGPT论文指南|揭秘8大ChatGPT提示词研究技巧提升写作效率【建议收藏】

点击下方▼▼▼▼链接直达AIPaperPass &#xff01; AIPaperPass - AI论文写作指导平台 公众号原文▼▼▼▼&#xff1a; ChatGPT论文指南|揭秘8大ChatGPT提示词研究技巧提升写作效率【建议收藏】 目录 1.写作方法 2.方法设计 3.研究结果 4.讨论写作 5.总结结论 6.书…

详解JavaScript中this指向

this 原理 this 是一个指针型变量&#xff0c;它指向当前函数的运行环境。 1.内存的数据结构 var obj { foo: 5 };2.函数 var obj { foo: function () {} };引擎会将函数单独保存在内存中&#xff0c;然后再将函数的地址赋值给foo属性的value属性。 由于函数是一个单独的…