JVM 类文件结构

Java领域JVM的类文件结构剖析 本文旨在全面解析Java类文件的二进制结构,帮助开发者深入理解Java程序在JVM中的表示形式。内容涵盖类文件各个组成部分的详细解析,包括其数据结构、编码方式和相互关联。文章首先介绍类文件的基本概念,然后逐部分解析类文件结构,接着通过实际案例演示如何解析类文件,最后讨论相关工具和应用场景。JVM:Java虚拟机,执行Java字节码的运行时环境字节码:JVM执行的指令集,介于源代码和机器码之间常量池:类文件中存储字面量和符号引用的表结构模块化系统:Java 9引入的模块化系统对类文件格式有新的要求。 阅读详情

整理自《深入理解Java虚拟机》

一、Class文件

类文件是由一个.java文件经过编译后形成的.class文件。class文件中包含了虚拟机指令集和符号表以及若干其他辅助信息。class文件交给JVM去运行,JVM再在不同的系统环境中执行代码。可以说这也是Java实现跨平台的重要一步。class文件不光只有Java可以生成,只要是运行在JVM上的语言经过不同的语言编译器编译后都可生成class文件在JVM上运行。

二、Class文件的组成

class文件由以下表构成(按顺序):

1、Magic Number(魔数):用于确定该文件是一个class文件。class文件中该值为四个16字节,值为0xCAFEBABE。

2、紧接着Magic Number的4个字节为版本号。高版本的JDK兼容低版本的JDK,但反过来不可以。

3、常量池(14种类型的表构成常量池)。

4、访问标志。

5、类索引(this)、父类索引(super)、接口索引。

6、字段表。

7、方法表。

8、属性表。属性表比较特殊,其跟在字段表、方法表后面。

三、详细介绍

1)常量池

常量池是Class文件中所占空间最大的数据项目。常量池中入口处为一个u2(两字节)类型的数字,表示常量池中有多少项常量。常量池中有14种表来表示常量,每个表都有相应编号(在开头)。比如CONSTANT_Class_info代表该类的信息。该表中的name_index若为2则代表指向第二个常量。第二项开头的索引为1,则代表为CONSTANT_Utf8_info表,后边的length长度的数字为该类全限定名的ASC码。(P169~P170)若常量池开头开头为0x16时说明有21项常量(p171),但常量项的索引却从1开始(1~21),这是因为当不引用常量池中任何一个项目时,将索引值置0。对于其他集合类型,如接口索引集合、字段表、方法表索引都是从0开始。

常量池主要存储下列两种内容:

(1)字面量

字符串、final static常量(constantValue会指向常量池中该值)等。

(2)符号引用

1、类和接口的全限定名。即带包名的完整类名,并把包中的 . 换为 / 分隔。

2、字段的名称(字段名)和字段描述符(字段所属的数据类型,比如int、char等)。

3、方法的名称(方法名字)和方法描述符(方法的参数列表和返回类型)。

14种表的详细结构见p169、p172。

2)访问标志

在常量池结束后,紧跟的两个字节为访问标志。该标志用于表示该class是类还是接口以及是否为public、abstract、synchronized等。

该标志有16个标志位(ACC_XXX),将符合条件的标志位的值叠加生成访问标志的值。

表的详细结构见p173。

3)类索引(this_class)、父类索引(super_class)、接口索引集合

紧接着访问标志为的为这三个索引,class文件中的继承关系即由这三个索引确定

(1)类索引(两字节)

类索引用于确定这个类的全限定名。也就是说名字光存在常量池中了还不够,得有人指向它。this_class指向常量池中自己类的CONSTANT_Class_info表(常量池中第this_class项),这个表中的index在去指向储存着真正类名的CONSTANT_Utf8_info表。

(2)父类索引(两字节)

该索引指向这个类父类的全限定名。由于Java没有多继承,所以除了Object类,该索引只有一个。如何寻找类名与类索引一致

(3)接口索引集合(多个两个字节组成的集合)

虽然Java不允许多继承,但是可以多实现接口。所以接口索引第一个两个字节代表的是实现了多少个接口,也就是接口的个数。implements语句后的接口按顺序从左到右排列在接口索引集合中。

表的详细结构见p175。

4)字段表(大部分类不止一个字段,多个字段表组成字段表集合)

字段表用于描述接口或类中声明的字段,一个字段表对应一个字段。字段包括类级变量(static)以及实例级变量(new出来的)。字段表有以下几项:

access_flags(存放该字段的修饰符,如public、static、final、volatile等)、name_index(字段的名字的索引,指向常量池第name_index项)、descriptor_index(该字段的数据类型或对象类型的描述符,指向常量池第descriptor_index项)、attributes_count(这个字段表跟随attributes_count个属性)、attributes(属性表集合)。

举个例子,比如

public long x ;

该字段表的第一项为0x0001,代表public;第二项为字段名,即x;第三项为描述符,这里为J,代表数据类型为long。

final static int x = 3,

如果该字段为final static修饰的常量,那么字段表屁股会跟随一个名称为ConstantValue的属性表,其指向常量池中该字段的值(常量池中CONSTANT_Integer_Info类型表,值为3)。

表的详细结构见p176~p177。

5)方法表(大部分类不止一个字段,多个字段表组成字段表集合)

如果理解了属性表,那么方法表也只是如法炮制。方法表描述类中的方法(包括static方法),一个方法表表示一个方法,多个方法表组成一个方法表集合。方法表有以下几项:

access_flags(存放该方法的修饰符,如public、static、final、synchronized等)、name_index(方法的名字的索引,指向常量池第name_index项)、descriptor_index(该方法的描述符,指向常量池第descriptor_index项)、attributes_count(这个字段表跟随attributes_count个属性)、attributes(属性表集合)。其中方法里面的代码会存在名为Code的属性表中

举个例子,比如:

public int show(int x, char[] args) {
    System.out.print(args[0] + x);
    return ++x;
}

方法描述符的顺序为先参数列表,后返回值。参数列表按照参数的严格顺序放在一组小括号中,紧接着的为方法返回值描述符。

该方法表的第一项为0x0001,代表public;第二项为方法名,即show;第三项为方法描述符,这里为(I[C)I。

还需注意两点:(1) 如果父类方法在子类中没有被重写,方法表中就不会出现来自父类方法的信息 。这一点在继承中尤为关键,千万不要以为子类中有父类方法的拷贝,子类是通过父类索引找到父类的class文件从而调用父类(继承得来)的方法。

class Father {
	public int Conf;
	
	public void init(int Conf) {
		this.Conf = Conf;
		this.init();
	}
	
	public void init() {
		System.out.println("Father running.......");
	}
	
}

public class Son extends Father{

	public void init() {
		System.out.println("Son running......");
	}
	
	public static void main(String[] args) {
		Son f = new Son();
		f.init(6);

	}

}

 

上图是子类通过Java ByteCode Editor解析出的方法表集合。可以看出子类只有一个自己的init方法。

(2) 编译器也会添加自己的某些方法,如<init>、<clint>,这两个方法留在类文件的加载来讲。

表的详细结构见p178~p179。

 

 

。

 

【Java正来-深入理解JVM】类文件结构 JVM的指令由一个字节长度、代表着某种特定操作含义的数字(成为操作码)以及跟随其后的零至多个代表此操作所需参数(操作数)而构成。JVM采用面向操作数栈而不是寄存器架构,所以大多只有一个操作码。 立即下载

相关推荐

UWB定位原理详细介绍

Hello大家好我是小智,今天我来给大家介绍下超宽带的定位原理,首先我们来讲下什么是UWB技术。 超宽带(Ultra Wide Band)简称UWB,和我们熟悉的WIFI、蓝牙技术一样属于通信技术的一种,UWB是一种无线载波通信技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,其所占的频谱范围很宽,右图是一种典型的正弦载波信号图。 UWB这种技术有什么特点呢? UWB系统结构实现简单;2.具有高速的数据传输能力;3.功耗低;4.安全性高;5.多径分辨能力强;6.可用于精确定位等特点。 UWB.

qq_35699674的博客 2万+

JVM——类文件结构

Java诞生之初的口号:“一次编写,到处运行(Write Once, Run Anywhere)”。 各个平台的虚拟机与所有平台都同意使用的程序存储格式——字节码(ByteCode)是构成平台无关性的基石。实现语言无关性的基础人生是虚拟机和字节码存储格式。Java虚拟机不和包括Java在内的如何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联,Class文件中包含了Java虚拟机指...

Richard331的博客 1174

保姆级教程:用OpenCV和MediaPipe在Python里实现实时手势识别(附完整代码)

本文提供了一份详细的Python教程,教你如何使用OpenCV和MediaPipe实现实时手势识别系统。从环境配置、手部关键点检测到手势分类算法,逐步讲解如何构建高精度手势识别应用,适用于智能家居控制、PPT操作等场景。教程包含完整代码示例和性能优化技巧,特别适合计算机视觉初学者和开发者实践。

weixin_28677005的博客 328

JVM之类文件结构

类文件结构1.无关性的基石:class文件2.Class类文件的结构Class文件描述1.Magic Number 和 文件版本2.常量池☆为什么要有常量池,常量池的作用是什么?实例:Class文件字节码分析工具-javap3.访问标志4.类索引、父类索引 与 接口索引集合5.字段表集合6.方法表7.属性表集合3.小结 我们都知道Java源文件,通过编译器能够生产相应的.class文件,也就是字节...

PassionZheng的博客 486

STM32+W5500实战:5分钟搞定FreeModbus TCP移植(附完整代码)

本文详细介绍了如何在STM32微控制器上,结合W5500以太网芯片,快速完成FreeModbus TCP协议栈的移植,构建稳定可靠的工业级Modbus TCP服务器。内容涵盖硬件连接、软件架构、驱动适配、核心移植代码实现及调试优化技巧,旨在提供可直接应用于实际项目的完整解决方案。

life6的博客 879

Java开发的企业排班系统

Java开发的企业排班系统,用了springboot框架,人脸识别是采用百度接口的方式实现

自学网站s.jf3q.com,菜鸟的成长之路 6013

JVM类文件结构

jvm的class文件的结构

shemuel的技术笔记 373

高速DAC设计与实现--AD9122

目录 芯片简介: 功能配置设计 高速DAC软件驱动设计 芯片简介: AD9122 是一款双通道16位高性能数模转换器(DAC),在800MSPS工作条件下其无杂散动态范围(SFDR)高达72dBc,最高可提供1200 MSPS采样速率。 高速DAC--AD9122电路原理图 硬件设计的电路原理图如上图所示,AD9122具备针对直接变频传输应用进行优化的特性,包括复数数字调制以及增益与失调补偿。DAC输出经过优化后可直接与模拟正交调制器无缝接口,便于后期使...

独木舟216的博客 1万+

JVM(三)类文件结构、类加载机制

Class文件结构、4种类加载器、双亲委派模型、栈帧结构

HK的博客 1281

如何把Excel的数据导入python?

Python数据分析——excl导入数据的简单方法(xlrd) 本文的初衷是发现网上很多Excel导入Python都没有结合具体Excel文档进行讲解,所以这篇文档将会呈现一个简单快速的Excel+Python的入门方法。 开发环境 Prerequisites: 在开始用Python导入Excel之前,要配置好自己的开发环境,最好有IDE(terminal也可)+安装相应的数据分析包。 IDE :pycharm,vscode,etc 数据分析包:matplotlib,xlrd,numpy,etc 导入数

qq_40783513的博客 7万+

YOLOv10改进策略【注意力机制篇】| 2024 蒙特卡罗注意力(MCAttn)模块,提高小目标的关注度

本文记录的是基于蒙特卡罗注意力(MCAttn)模块的YOLOv10目标检测改进方法研究。利用提高的跨尺度特征提取能力,使模型能够更好地传递和融合提取的多尺度特征,提高对小目标的关注度。Exploiting Scale-Variant Attention for Segmenting Small Medical Objects使用一种基于随机采样的池化操作来生成尺度无关的注意力图。它从三个不同尺度(3×33×33×3、2×22×22×2和1×11×11×1,即池化张量)中随机选择一个1×11×11×1注意力图

Limiiiing的博客 2187

JVM类文件结构详解

在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。 所以 Java 程序运行时比较高效,而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。

weixin_46425661的博客 1186

手把手教你完成基于cnn的手写数字识别系统MATLAB语言

手写数字识别是经典的 CNN 分类应用之一,常用的数据集就是 MNIST 手写数字数据集,包含 0~9 这 10 个数字的手写图片,每个数字都由 6 万幅训练图像和 1 万幅测试图像构成。为了便于直观分析,这里选择 MATLAB 工具箱提供的 DigitDataset 进行训练识别,读者也可以直接利用 MNIST 数据集或者自己设计的数据集进行实验。其中,数据集文件夹 db 如图 所示。在数据集文件夹 db 里面对每个数字都建立了子文件夹,各自包含 1000 幅 28×28 大小的二维灰度图像。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 1368

JVM(二)类文件结构

类文件结构介绍

qq_44818304的博客 1229

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

JVM-类文件结构

一个类可能实现了多个接口,因此用接口索引集合来描述。name_index 是一个索引值,它指向常量池中一个 CONSTANT_Utf8_info 类型常量,此常量代表这个类(或接口)的全限定名,这里 name_index 值若为 0x0002,也即是指向了常量池中的第二项常量。类索引和父类索引用两个 u2 类型的索引值表示,它们各自指向一个类型为 CONSTANT_Class_info 的类描述符常量,通过该常量总的索引值可以找到定义在 CONSTANT_Utf8_info 类型的常量中的全限定名字符串。

Dc253061007的博客 1074

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

JVM—类文件结构

Class文件是一组以字节为基础单位的二进制流,各个数据项目严格按照顺序排列紧凑的在文件中,中间没有任何分隔符。Class文件采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构只有“无符号数”和“表”两种数据类型无符号数:属于基本数据类型,以u1、u2、u4、u8分别表示1个字节,2个字节...这样。可以用来描述索引引用、数字、数量值等。表:是由多个无符号数或者其他表作为数据项构成的有层次关系的复合数据类型,一般以_info结尾,整个Class本质上也可以视作一张表。

摸鱼小小虫的博客 1137

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

JVM类文件结构:揭秘Java字节码的奥秘

在Java开发中,了解JVM(Java虚拟机)类文件结构是至关重要的。JVM类文件是Java源代码编译后生成的二进制文件,它包含了Java字节码的指令集和其他相关信息。本文将深入探讨JVM类文件的结构,包括文件格式、常量池、字段和方法表等内容,帮助读者更好地理解Java字节码的内部工作原理。JVM类文件结构是理解Java字节码的关键所在。通过深入研究JVM类文件的基本结构、常量池表以及其他重要部分,我们可以更好地理解Java程序的编译和执行过程。

一名Java语言狂热分子。 817

深入理解JVM - 类文件结构

前言 ​ JVM的类文件结构基本都会要记忆的内容,我相信你也记不住,当然我也是记不住的,所以这里只会列出大致的类文件结构,我们需要大致了解类文件结构是怎么一回事就行了,具体到那个位存哪个内容,内容确实太多了,感兴趣可以直接去读书中对应的第6章 类文件结构这一个章节的内容。 ​ 类文件结构个人认为需要注意的点就是这几点:大致的类文件结构,部分Jdk的特性如何通过改动class文件结构实现,比如泛型,自动拆装箱,动态代{过}{滤}理,lambada语法等。 概述: ​ 其实主要内容就是介绍CLASS的文

qfchenjunbo的博客 193

JVM整体架构&类文件结构

1.源码编译:通过Java源码编译器将Java代码编译成JVM字节码(.class文件)2.类加载:通过ClassLoader及其子类来完成JVM的类加载3.类执行:字节码被装入内存,进入JVM虚拟机,被解释器解释执行4.JVM虚拟机中主要是由三部分构成,分别是类加载子系统、运行时数据区、执行引擎。

weixin_44132970的博客 398

JVM-Class类文件结构笔记

JVM-Class类文件结构速成,基于《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》第6章

m0_52133525的博客 224

JVM类文件结构深度解析:跨平台基石与字节码探秘

类文件是Java生态的通用中间表示,其精巧设计体现了计算机科学中抽象与实现的完美平衡。掌握这一结构,是我们开发者通向高级Java开发的必经之路!

m0_73804764的博客 1159

gh_mirrors/jvm9/jvm类文件结构详解:从魔数到属性表

你是否曾经疑惑:为什么Java能实现"一次编写,到处运行"?为什么Scala、Kotlin等语言能在JVM上无缝运行?答案就隐藏在`.class`文件的二进制结构中。本文将带你深入探索JVM类文件的底层结构,从神秘的"魔数"到复杂的属性表,全面解析JVM如何通过这个二进制格式实现语言无关性和平台无关性。 读完本文你将掌握: - 类文件的完整二进制结构 - 魔数与版本号的编码规则 - 常量池的组织...

gitblog_01178的博客 1074

细说JVM(类文件结构(二))

一、前言 上一篇博客的地址:细说JVM(类文件结构(一)) 二、类文件分析 5、类索引、父类索引与接口索引集合 在访问标志access_flags后接下来就是类索引(this_class)和父类索引(super_class),这两个数据都是u2类型的,而接下来的接口索引集合是一个u2类型的集合,class文件由这三个数据项来确定类的继承关系。由于Java中是单继承,所以父类索引只有一个;但...

啦啦啦的博客 790

JVM学习-类文件结构 类加载

使用场景想加载非 classpath 随意路径中的类文件通过接口来使用实现,希望解耦时,常用在框架设计这些类希望予以隔离,不同应用的同名类都可以加载,不冲突,常见于 tomcat 容器步骤继承 ClassLoader 父类要遵从双亲委派机制,重写 findClass 方法不是重写 loadClass 方法,否则不会走双亲委派机制读取类文件的字节码调用父类的 defineClass 方法来加载类使用者调用该类加载器的 loadClass 方法破坏双亲委派模式。

2302_77426533的博客 1420
上一篇: [转]Java并发 Volatile关键字解析
下一篇: Java 深入理解泛型的强制转型及自动转型
donCoder
博客等级 码龄9年 65粉丝 79原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值