【注释和反射】类加载的过程

这篇具有很好参考价值的文章主要介绍了【注释和反射】类加载的过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

继上一篇博客【注释和反射】获取class类实例的方法-CSDN博客

目录

三、类加载的过程

例子


三、类加载的过程

在Java虚拟机(JVM)中,类加载是一个将类的字节码文件从文件系统或其他来源加载到JVM的内存中,并将其转换为类或接口的过程。类加载的过程主要可以分为三个步骤:加载(Loading)、链接(Linking)和初始化(Initialization)。

【注释和反射】类加载的过程,java,java,开发语言,intellij-idea,class

(1)加载(Loading):

加载是类加载过程的第一步,主要由类加载器完成。类加载器负责从文件系统、网络或其他来源读取类的字节码文件,并将其加载到JVM的内存中。加载过程主要完成以下三件事:

  1. 通过类的全限定名获取定义此类的二进制字节流。
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

Java提供了三种类加载器:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和系统类加载器(System ClassLoader)。这些类加载器之间存在父子关系,但这里的父子关系并非继承关系,而是包含关系。

(2)链接(Linking):

链接过程可以细分为验证(Verification)、准备(Preparation)和解析(Resolution)三个阶段。

  1. 验证:验证阶段主要是为了确保加载的类文件信息符合JVM规范,不会危害虚拟机自身的安全。
    1. 验证的内容包括文件格式、元数据、字节码和符号引用等。
  2. 准备:准备阶段是为类的静态变量(static变量)分配内存,并设置默认的初始值。这些内存都将在方法区中进行分配。
    1. 需要注意的是,这里所说的初始值通常情况下是数据类型默认的零值,而不是被显式赋值。
  3. 解析:解析阶段是将常量池内的符号引用替换为直接引用的过程。
    1. 符号引用以一组符号来描述所引用的目标,而直接引用则是直接指向目标的指针、相对偏移量或者一个能间接定位到目标的句柄。

(3)初始化(Initialization):

初始化阶段是类加载过程的最后一步,主要完成类的静态变量的初始化工作。静态变量的初始化是由类构造器<clinit>()方法完成的。这个方法由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的。

初始化阶段,只有当类被主动使用时才会触发。主动使用的情况包括:创建类的实例、访问某个类或接口的静态变量、调用类的静态方法、反射(如Class.forName())、初始化一个类的子类(会首先初始化子类的父类)、Java虚拟机启动时被标明为启动类的类(Java Test)、JDK 7开始提供的动态语言支持等。

需要注意的是,类的加载过程必须按照顺序开始,但并非必须按照顺序完成。因为链接阶段中的某些过程(如解析)可能需要在初始化阶段中根据实际运行情况才能确定。此外,JVM规范并没有规定解析阶段一定要在初始化之前完成,只要求了在类和接口被使用前完成解析。

例子

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


class A{
  static {
    System.out.println("A类的静态代码块初始化");
    m = 300;
  }

  static int m = 100;

  public A(){
    System.out.println("A类的无参构造初始化");
  }
}

【注释和反射】类加载的过程,java,java,开发语言,intellij-idea,class

当运行Test02类的main方法时,以下是详细步骤:

  1. 加载Test02:因为Test02包含main方法,它是程序的入口点,所以JVM首先加载Test02类。但是Test02类本身没有静态变量和静态代码块需要初始化,所以这一步几乎没什么要做的。

  2. 执行main方法:在main方法中,首先创建A类的一个实例a

  3. 加载A:为了创建A的实例,JVM需要加载A类。在加载类的过程中,JVM会执行以下操作:

    • 分配内存给A类的静态变量。
    • 初始化A类的静态变量。在这个过程中,首先会执行静态代码块,然后按照声明的顺序初始化静态变量
  4. 执行静态代码块:在静态代码块中,输出了“A类的静态代码块初始化”,然后将m赋值为300。但是,这里有一个关键的陷阱。

  5. 初始化静态变量m:紧接在静态代码块执行之后,静态变量m被初始化为100。这个赋值操作实际上覆盖了静态代码块中的赋值,因为静态变量的初始化语句(static int m = 100;)在静态代码块之后执行。

  6. 创建A的实例:现在,A类已经加载并初始化,可以创建其实例了。调用A的无参构造函数,输出“A类的无参构造初始化”。

  7. 输出m的值:最后,main方法中System.out.println(A.m);输出静态变量m的当前值,由于m最终被赋值为100,所以输出结果是100。

【注释和反射】类加载的过程,java,java,开发语言,intellij-idea,class

综上所述,程序的输出结果为:文章来源地址https://www.toymoban.com/news/detail-857407.html

A类的静态代码块初始化
A类的无参构造初始化
100

到了这里,关于【注释和反射】类加载的过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java类加载过程

    目录 概述  类加载时机 类加载过程 加载 验证 文件格式验证 元数据验证 字节码校验 符号引用校验 准备 解析 初始化 类加载器 双亲委派模型 双亲委派被破坏           Java虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成

    2023年04月20日
    浏览(33)
  • Java语言----反射、枚举以及lambda表达式

    目录 一.反射 1.1反射的基本情况 1.2反射中最重要的类 1.2.1 Class类 1.2.2Field类 1.2.3Constructor类 1.2.4Method类 1.3反射优缺点  二.枚举 2.1概念 2.2枚举(enum)类方法 2.3枚举的构造 三.Lambda表达式 3.1Lambda介绍 3.2 函数式接口 3.3使用lambda表达式 3.2.1不使用Lambda表达式调用 3.2.2使用Lambda表

    2024年02月08日
    浏览(49)
  • [JVM] Java类的加载过程

    在Java中,类的加载是指在程序运行时将类的二进制数据加载到内存中,并转化为可以被JVM执行的形式的过程。类的加载过程主要包括以下几个步骤: 加载 (Loading):通过类的全限定名,使用类加载器将类的二进制数据加载到JVM中。类加载器会根据类的名称找到对应的字节码

    2024年01月16日
    浏览(36)
  • 【Java】JVM执行流程、类加载过程和垃圾回收机制

    JVM,就是Java虚拟机,Java的的程序都是运行在JVM当中。 程序在执行之前先要把java源代码转换成字节码(class文件),JVM 首先需要把字节码通过一定的方(类加载器(ClassLoader)) 把文件加载到内存中的运行时数据区(Runtime Data Area) ,而字节码文件是 JVM 的一套指令集规范,并

    2024年02月16日
    浏览(50)
  • 04.阿里Java开发手册——注释规约

    【强制】 类、类属性、类方法的注释必须使用 Javadoc 规范,使用 /**内容*/ 格式,不得使用 // xxx 方式。 说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Javadoc 可以正确输出相应注释;在 IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义

    2024年01月16日
    浏览(43)
  • 《深入理解Java虚拟机》读书笔记: 虚拟机类加载的时机和过程

    虚拟机类加载的时机和过程 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中验证、准备、解析3个

    2024年02月12日
    浏览(43)
  • Java项目使用intellij-IDEA查看依赖包版本是否有冲突(方法及工具)附截图

    编译器及版本 idea-ultimate 依赖管理工具 maven Step1:点击右侧的maven Step2:右键依赖项,点击分析依赖关系 Step3:可以在模块名位置进行切换,左侧三角的标志则表示该包引入了多个版本,有冲突 Step4:可以看到当前这个包被引入了两个版本的 Step5:右键冲突的包名,可以看到

    2024年02月15日
    浏览(106)
  • 反射 p3 类加载

    反射机制是Java实现动态语言的关键,也就是通过反射实现类动态加载。 静态加载: 编译时加载相关的类,如果没有则报错,依赖性太强。 动态加载: 运行时加载相关的类,如果运行时不用该类,即使不存在该类,也不会报错,降低了依赖性。 代码演示: 当创建对象时(

    2024年02月16日
    浏览(26)
  • 【华为OD机考 统一考试机试C卷】反射计数(C++ Java JavaScript Python C语言)

    2023年11月份,华为官方已经将 华为OD机考:OD统一考试(A卷 / B卷)切换到 OD统一考试(C卷)和 OD统一考试(D卷) 。根据考友反馈:目前抽到的试卷为B卷或C卷/D卷,其中C卷居多 ,按照之前的经验C卷D卷部分考题会复用A卷/B卷题,博主正积极从考过的同学收集C卷和D卷真题,

    2024年02月19日
    浏览(46)
  • 【C#】反射机制,动态加载类文件

    【C#】编号生成器(定义单号规则、固定字符、流水号、业务单号) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/129129787 【C#】日期范围生成器(开始日期、结束日期) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/129040663 【C#】组件化开发,调用dll组件方法 本文链接

    2024年02月11日
    浏览(70)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包