首页 > 编程语言 >Java的类加载机制

Java的类加载机制

时间:2024-01-15 16:48:29浏览次数:41  
标签:初始化 Java 启动 虚拟机 应用程序 机制 加载

Java的类加载机制是指在Java程序运行时,将类文件加载到内存中的一系列步骤。Java的类加载机制遵循着“按需加载”的原则,也就是说,只有在需要用到某个类的时候,才会将这个类的相关信息加载到内存中。这种“按需加载”的设计使得Java程序具备了很好的灵活性和效率。

Java的类加载器主要分为三类:启动类加载器、扩展类加载器和应用程序类加载器。不同的类加载器负责加载不同的类,在Java的类加载机制中,具有不同级别的权限和不同的类搜索路径。下面我们来详细的介绍一下Java的类加载机制。

1.加载机制

Java的类加载机制主要分为三个过程:加载、连接和初始化。这三个过程的顺序是固定的,但是每个过程中的细节却是不同的。下面我们来详细介绍一下这三个过程。

1.1 加载

Java的类加载器会根据类的全限定名来加载类,当需要使用某个类时,如果该类还未被加载进内存,则需要执行一下步骤进行加载:

1.1.1. 通过类的全限定名找到对应的class文件,这里的class文件可以是.java文件经过编译之后生成的.class文件,也可以是通过其他方式生成的.class文件。

1.1.2 将class文件中的二进制数据读取到内存中,并将其转换为方法区的运行时数据结构。

1.1.3 创建由该类所属的java.lang.Class对象。该对象可以理解为,是对类的各种数据(如名称、访问修饰符、方法、成员变量等)的封装。

在加载类时,类加载器除了加载某个具体的类外,还需要将这个类所依赖的类也加入到内存中。这种依赖性是多层级的,也就是说,被依赖的类又可能会去依赖其他类,所以在加载一个类时,通常需要将其类图中所有的类都加载进来。

1.2 连接

Java虚拟机在加载类之后,需要对类进行连接,连接分为三个步骤:验证、准备和解析。

1.2.1. 验证

在这个步骤中,Java虚拟机主要确保所加载的类的正确性。验证过程主要包括文件格式验证、元数据验证、字节码验证和符号引用验证等。其目的在于确保目标.class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机运行时环境安全。

1.2.2. 准备

在准备阶段,Java虚拟机为类的静态变量分配内存,并设置变量的初始值。这里需要注意的是,在这个阶段中分配的内存并不包含那些用户自定义的初始化值,这些值在初始化阶段中进行设置。

1.2.3. 解析

Java在这个阶段中将常量池中的符号引用转为直接引用。通过符号引用,虚拟机得知该类访问其他的类或者类中的字段、方法等,但在类初始化时,需要缓存这些直接引用,以便于直接调用。

1.3 初始化

在类的准备阶段,Java虚拟机已经为静态变量分配了内存并设置了初值,但是这些静态变量”赋初值“的动作并没有完成。初始化阶段,会为静态变量设置用户自定义的初始化值,并执行类构造器<clinit>()方法,以执行初始化操作。

此时,类的准备和初始化阶段已经执行结束,Java的类加载机制总的过程也就结束了。

2.三种类加载器

Java类加载器为了适应Java程序的变化和复杂性,把不同的加载器负责不同的类,组成一个层次化的结构,这样就产生了三种不同级别的类加载器:启动类加载器、扩展类加载器和应用程序类加载器。

2.1 启动类加载器(BootstrapClassLoader)

启动类加载器是Java虚拟机中最基础的类加载器,它主要负责加载第一个被虚拟机执行的特殊类——java.lang.ClassLoader,该类在虚拟机启动时被加载,并提供了所有其它类加载器的基础,也就是说,所有的类加载器都直接或者间接地继承自这个类。

启动类加载器由C++语言实现,并不是Java语言实现。此外,在Java中也无法通过代码获取到该类加载器对象的引用。

2.2 扩展类加载器(ExtensionClassLoader)

扩展类加载器是用来加载Java系统扩展库的类加载器,负责加载$JAVA_HOME/lib/ext目录下的类库。扩展类加载器是在启动类加载器之后启动的,它也是纯Java代码实现的类加载器。

在Java中,扩展类加载器的父加载器是启动类加载器。这种方式保证了系统类库在运行时的稳定性和安全性。

2.3 应用程序类加载器(ApplicationClassLoader)

应用程序类加载器是应用程序中默认的类加载器。它主要负责加载应用程序classpath下的类,也就是我们平时自己写的Java代码所编译出来的.class文件。

应用程序类加载器是在扩展类加载器之后启动的,也是纯Java实现的类加载器。由于应用程序类加载器在Java中属于最高的加载器级别,所以我们通常也称之为“系统类加载器”。

应用程序类加载器的父类加载器是扩展类加载器,父类加载器负责加载Java系统库中的类。当应用程序类加载器无法加载一个类时,会向上委托其父类加载器进行加载,直到启动类加载器都找不到才会抛出ClassNotFoundException异常。

3.双亲委派机制

Java的类加载机制采用的是双亲委派模型,这是一种经典的类加载机制,也是Java的类加载机制得以广泛使用的重要原因之一。

所谓“双亲委派”,就是在类加载的过程中,一个类加载器在加载某个类时,会先委托给它的父类加载器进行加载。如果父类加载器无法加载成功,再由自己来加载该类。这样做的好处在于,保证Java虚拟机安全、稳定地运行,避免出现恶意代码污染系统。

在Java中,类加载器会一直询问其父加载器是否能够加载某个类,直到达到启动类加载器(即基类加载器)时,如果该类还没有被加载,此时才交由启动类加载器去加载这个类。因为启动类加载器是由Java虚拟机自身实现的,任何类都可以使用它来进行加载,所以启动类加载器就成为了Java虚拟机中的“保护神”。

双亲委派机制可以防止Java程序中出现重复的类,保障了上层的ClassLoader不会出现被下层的ClassLoader覆盖的情况,从而保护了Java程序的安全性。

标签:初始化,Java,启动,虚拟机,应用程序,机制,加载
From: https://www.cnblogs.com/lyh233/p/17965684

相关文章

  • Vue 项目离线安装 ArcGIS for JavaScript
    注意:arcgis-js-api在4.18及之后版本,可以通过npminstall@arcgis/[email protected]直接安装在写些博客时,npm能安装的最新版为4.28.10,下面以4.28.10为例,讲解离线安装。在vue3项目中,通过npminstall@arcgis/[email protected]安装,但默认是半本地化的,因为assests资源是通过https://js.ar......
  • PDF.js实现按需分片加载pdf文件-包含前后端开发源码和详细开发教程
    PDF.js实现按需分片加载pdf文件-包含前后端开发源码和详细开发教程:https://blog.csdn.net/qq_29864051/article/details/130742657?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170529842016800186594900%2522%252C%2522scm%2522%253A%252220140713.130102334..%252......
  • java Flink 校验接口数据
    要使用Java编写Flink程序来校验接口的数据,可以按照以下步骤进行操作。首先,需要引入相关依赖包。在pom.xml文件中添加如下依赖项:org.apache.flinkflink-streaming-java_2.12{FLINK版本号}其中{FLINK版本号}应该被替换为所使用的Flink版本号。创建一个新的Java类,并导入必要......
  • 精彩推荐 |【Java技术专题】「重塑技术功底」攻破Java技术盲点之剖析动态代理的实现原
    背景介绍在Java编程中,动态代理的应用非常广泛。它被广泛应用于SpringAOP框架、Hibernate数据查询、测试框架的后端mock、RPC以及Java注解对象获取等领域。静态代理和动态代理与静态代理不同,动态代理的代理关系是在运行时确定的,这使得它在灵活性上更胜一筹。相比之下,静态代理的代理......
  • Java小细节之数组什么情况下相等,什么情况下不相等
    int[]a={1,2,3};int[]b=a;System.out.println(a==b);此时输出trueint[]a={1,2,3};int[]b={1,2,3};System.out.println(a==b);此时输出为false这是因为数组的机制,int[]b=a,相当于让b和a同时管理这个数组,a和b都是代表同一个数组,所以a==b是正确的,此时对数......
  • SparkSQL 操作Hive In Java
    本文的前提条件:SparkSQLinJava1.增加POM依赖<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.33</version></dependenc......
  • 【JaveWeb教程】(2)Web前端基础:JavaScript入门不再难:一篇文章教你轻松搞定JavaScript的
    目录1介绍2引入方式3基础语法3.1书写语法3.2变量3.3数据类型和运算符4函数4.1第一种定义格式4.2第二种定义格式html完成了架子,css做了美化,但是网页是死的,我们需要给他注入灵魂,所以接下来我们需要学习JavaScript,这门语言会让我们的页面能够和用户进行交互。1介绍通过代......
  • SpringBoot 2.x 正式停更了。Java 8 就看 Solon 的了!
    最近有好多个新闻说:SpringBoot2.x正式停更了,Java8怎么办?当然用Solon喽!Solon,同时支持jdk8,jdk11,jdk17,jdk21。也支持graalvmnativeimage。既支持java8,也支持java21的:@SolonMainpublicclassApp{publicstaticvoidmain(String[]args){Sol......
  • 安装 Java 开发工具包(JDK)
    在线安装在CentOS上安装JDK打开终端,并使用root或具有管理员权限的用户登录。更新系统软件包列表,确保使用最新的软件包版本:sudoyumupdate安装JDK的依赖包:sudoyuminstalljava-1.8.0-openjdk-devel请注意,此处安装的是OpenJDK8版本的JDK。如果你需要安......
  • Java学习路线
    本套视频教程所有配套资料领取方式如下:方式1:访问黑马官网可下载:www.itheima.com?bz方式2:关注黑马程序员公众号,回复关键词:领取资源02学习+Q群625260577,告别孤单,共同进步!2024黑马程序员Java学习路线图如何下载资料Java最高效学习路线图(依次向下顺序学习即可)Java基础:Java入门基础视......