深入理解java虚拟机:类文件结构(1)

news2025/7/20 20:57:07

文章目录

  • 1. 概述
  • 2. Class类文件的结构
    • 2.1 魔数与Class文件的版本
    • 2.2 常量池
    • 2.3 访问标志
    • 2.4 类索引、父类索引与接口索引集合
    • 2.5 字段表集合

1. 概述

如果计算机的CPU指令集就只有x86一种,操作系统就只有Windows一种,那也许就不会有Java语言的出现。Java在刚刚诞生之时曾经提出过一个非常著名的宣传口号:“一次编写,到处运行(Write Once,Run Anywhere)”,这句话充分表达了软件开发人员对冲破平台界限的渴求。在无时无刻不充满竞争的IT领域,不可能只有Wintel存在,我们也不希望只有Wintel存在,各种不同的硬件体系结构和不同的操作系统定将会长期并存发展。“与平台无关”的理想最终实现在操作系统的应用层上:Sun公司及其他虚拟机提供商发布了许多可以运行在各种不同平台上的虚拟机,这些虚拟机都可以载入和执行同一种平台无关的字节码,从而实现程序的“一次编写,到处运行”。

在这里插入图片描述

2. Class类文件的结构

img

Class的结构不想XML等描述语言,由于它没有任何分隔符号,所以上述的数据项,无论是顺序还是数量,都是被严格限定的,哪个字节代表什么含义,长度是多少,先后顺序如何,都不允许改变

2.1 魔数与Class文件的版本

每个Class文件的头4个字节称为魔数(Magic Number),它的唯一作用是用于确定这个文件是否为一个能被虚拟机接收的 Class 文件。

这个魔数为:0xCAFEBABE

第5和第6个字节是次版本(minor_version)

第7和第8个字节是主版本号(major_version)

查看一个class文件,结果如下:
在这里插入图片描述

下表列举了从JDK1.1到1.7之间,主流JDK版本编译器输出的默认和可支持的Class文件版本号。

在这里插入图片描述

2.2 常量池

紧接着主次版本号之后的是常量池入口,是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时也是Class文件中第一个出现的表类型数据项目

由于常量池中常量的数量是不固定的,所以在常量池的入口需要放置一项2类型的数据,代表常量池容量计数值(constant_pool_count)。与Java中的语言习惯不一样的是,这个容量计数是从1而不是0开始的,如图6-3所示,常量池容量(偏移地址:0x00000008)为十六进制数0x0016,即十进制的22,这就代表常量池中有21项常量,索引值为1~21。制定Class文件格式规范时,将第0项常量空出来是有特殊考虑的,这样做是为了满足后面某些指向常量池的索引值的数据在特定情况下需要表达“不引用任何一个常量池项目”的意思,这种情况就可以把索引值置为0来表示。Class文件结构中只有常量池的容量计数是从1开始的,对于其他集合类型,包括接口索引集合、字段表集合、方法表集合等的容量计数都与一般习惯相同,是从0开始的。

第9和第10个字节是常量池计数值,因为常量池中常量不固定,所以在常量池入口放置一项u2类型的数据
在这里插入图片描述
常量池中的每一项常量都是一个表,共有11种结构“各不相同的表结构数据,这11种表都有一个共同的特点,就是表开始的第一位是一个ul类型的标志位(tag,取值为1至12,缺少标志为2的数据类型),代表当前这个常量属于哪种常量类型,11种常量类型所代表的具体含义如下所示
在这里插入图片描述
图6-3,常量池的第1个常量是07,从表6-1查表可知道该常量类型为CONSTANT_Class_info,表示类或接口的符号引用。

Oracle公司已经为我们准备好一个专门用于分析Class文件字节码的工具:javap

javap -verbose [class文件名]

举个例子,可以看到一共18个常量全部显示

C:\>javap -verbose TestClass
public class com.monk.TestClass                
  minor version: 0                             
  major version: 55                            
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER        
  this_class: #3                          // com/monk/TestClass           
  super_class: #4                         // java/lang/Object             
  interfaces: 0, fields: 1, methods: 2, attributes: 1                     
Constant pool:                                                            
   #1 = Methodref          #4.#15         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#16         // com/monk/TestClass.m:I       
   #3 = Class              #17            // com/monk/TestClass           
   #4 = Class              #18            // java/lang/Object             
   #5 = Utf8               m                                              
   #6 = Utf8               I                                              
   #7 = Utf8               <init>                                         
   #8 = Utf8               ()V                                            
   #9 = Utf8               Code                                           
  #10 = Utf8               LineNumberTable                                
  #11 = Utf8               inc                                            
  #12 = Utf8               ()I                                            
  #13 = Utf8               SourceFile                                     
  #14 = Utf8               TestClass.java
  #15 = NameAndType        #7:#8          // "<init>":()V
  #16 = NameAndType        #5:#6          // m:I
  #17 = Utf8               com/monk/TestClass
  #18 = Utf8               java/lang/Object

这里我们将11中常量项的结构定义总结成下表

在这里插入图片描述在这里插入图片描述

2.3 访问标志

在常量池结束之后,紧接着的2个字节代表访问标志(access_flags),这个标志用于识别一些类或接口层次的访问信息,包括:这个Clss是类还是接口:是否定义为public类型;是否定义为abstract类型;如果是类的话,是否被声明为final,等等。具体的标志位及标志的含义见下表
在这里插入图片描述

2.4 类索引、父类索引与接口索引集合

类索引(this_class)和父类索引(super_class)都是一个u2类型的数据,而接口索引集合(interfaces)是一组u2类型的数据的集合

例如上面使用javap命令生成的类信息中找出对应的类和父类的常量

  #3 = Class              #17            // com/monk/TestClass           
  #4 = Class              #18            // java/lang/Object        

2.5 字段表集合

字段表field info用于描述接口或类中声明的变量。字段(field)包括了类级变量或实例级变量,但不包括在方法内部声明的变量。我们可以想一想在Java中描述一个字段可以包含什么信息?可以包括的信息有:字段的作用域(public、private、protected修饰符)、是类级变量还是实例级变量(static修饰符)、可变性(final)、并发可见性(volatile修饰符,是否强制从主内存读写)、可否序列化(transient修饰符)、字段数据类型(基本类型、对象、数组)、字段名称。这些信息中,各个修饰符都是布尔值,要么有某个修饰符,要么没有,很适合使用标志位来表示。而字段叫什么名字、字段被定义为什么数据类型,这些都是无法固定的,只能引用常量池中的常量来描述。下表中列出了字段表的最终格式。

在这里插入图片描述

这里也有access_flags,与前面提到的访问标志类似
在这里插入图片描述
name_indexdescriptor_index:字段的简单名称和描述符

名称很好识别,比如已/符号出现的一些名称,比较复杂的是描述符,下面我们看看描述符。描述符的
作用是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。根据描述符规则,基本数据类型(byte、char、double、float、int、long、short、boolean)及代表无返回值的void类型都用一个大写字符来表示,而对象类型则用字符L加对象的全限定名来表示,详见下表

在这里插入图片描述
对于数组类型,每一维度将使用一个前置的[字符来描述,如一个定义为java,lang.String类型的二维数组,将被记录为:[[Ljava/lang/String;,一个整型数组int[]将被记录为[I

对于方法来说,按照先参数列表,后返回值的顺序描述,参数列表按照参数的严格顺序放在一组小括号()中,比如方法void inc()的描述符为()V,方法 java.lang.String toString()的描述符()Ljava/lang/String;比如第8个常量和第12个常量的描述符表示:

 #8 = Utf8               ()V      // 表示空参空返回                                      
 #9 = Utf8               Code                                           
 #10 = Utf8               LineNumberTable                                
 #11 = Utf8               inc
 #12 = Utf8               ()I		// 表示空参返回Integer

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

云原生:容器与微服务

目录 一、虚拟化与容器 1.1 虚拟机 1.2 容器 1.3 Docker 1.4 Docker代码示例 二、微服务 2.1 微服务的概念 2.2 微服务的特点 三、为什么使用微服务 3.1 微服务的优缺点 3.2 云原生的支持服务 云原生技术使组织能够在新式动态环境&#xff08;如公有云、私有云和混…

攻防世界-pwnCTFM-Off_By_one漏洞与Tcachebin绕过

攻防世界-pwnCTFM-Off_By_one漏洞与Tcachebin绕过 保护机制 healerhealer-virtual-machine:~/Desktop/pwnCTFM/attachments$ checksec pwn [*] /home/healer/Desktop/pwnCTFM/attachments/pwnArch: amd64-64-littleRELRO: Full RELROStack: Canary foundNX: …

线性判别分析(机器学习)

目录 线性判别分析的原理 LDA的降维过程如下 线性判别分析&#xff08;LDA&#xff09; 是一种有监督的线性降维算法。 与PCA不同&#xff0c;LDA是为了使降维后的数据点尽可能地容易被区分 线性判别分析的原理 线性判别分析是对于给定的训练集&#xff0c;设法将样本投影到…

基于HTML+CSS+JavaScript+Bootstarp响应式健身网站(web前端期末大作业)

网站题目> &#x1f3c0;校园篮球网页设计、⚽足球体育运动、&#x1f93d;体育游泳运动、&#x1f3d3;兵乓球 、&#x1f3be;网球、等网站的设计与制作。 二、✍️网站描述> &#x1f3f7;️ 大学生校园运动静态HTML网页设计作品&#xff0c;采用DIV CSS布局制作&am…

数据结构体进阶链表【带头双向循环链表,单向链表的优化,从根部解决了顺序表的缺点】一文带你深入理解链表

前言&#xff1a; 对于链表&#xff0c;上一篇的单链表解决了顺序表的一部分缺陷&#xff0c;但并没有彻底的解决顺序表的问题&#xff0c;比如在进行单链表尾插尾删的时候还是需要进行遍历找尾&#xff0c;并没有达到全部的O(1)&#xff0c;并且在头插的时候还要分情况来考虑&…

【ASM】字节码操作 工具类与常用类 AdviceAdapter 介绍 打印方法进入 和 方法退出 的参数

文章目录 1.概述2. AdviceAdapter类2.1 class info2.2 fields2.3 constructors2. 4 methods2.案例2.1 打印方法参数3.总结1.概述 在上一篇文章:【ASM】字节码操作 工具类与常用类 Printer、ASMifier、Textifier 介绍 我们简单的介绍了 Printer、ASMifier、Textifier 三个类的…

idea2021版本创建一个javaweb项目(含额外知识--添加tomcat相关jar包)

前言&#xff1a; 建立一个javaweb项目需要用到JDK、idea、Tomcat 1. JDK是11版本的 2.IDEA是2021版本的 3.Tomcat是8.5版本的 这些下载在我的其他文章里面也有讲到下载和应用&#xff0c;大致都是殊途同归的 一、打开ided&#xff0c;按照以下步骤点击创建一个工程项目…

X11 Xlib截屏代码所遇问题及初步分析

综合了两篇博客中的例程并做一定修改&#xff0c;得到了基于X11 Xlib的截屏代码。 两篇博客链接分别如下&#xff1a; X11 截图与鼠标事件-SkyMei777-ChinaUnix博客 xlib实现截图报错-编程语言-CSDN问答 C代码如下&#xff1a; #include <stdio.h> #include <std…

[附源码]SSM计算机毕业设计自治小区物业设备维护管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

TK选品技巧 | 听说TikTok畅销品都是这样来的

9月16日消息&#xff0c;TikTok Shop发布东南亚99大促战报&#xff0c;此次战报数据包含了马来西亚、新加坡、菲律宾、越南和泰国五国销售数据&#xff0c;战报显示&#xff0c;此次东南亚99大促总GMV增幅达156%&#xff0c;总live GPM增幅达130%&#xff0c;订单量增幅达128%&…

基于springboot的社区疫情管理系统源码

1、项目介绍 基于springboot的社区疫情管理系统拥有三种角色&#xff1a;超级管理员、普通管理员、用户 超级管理员&#xff1a;管理员和用户管理、人员检测信息管理、外来人员报备管理、防疫须知管理、疫情用品类型管理、疫情用品管理、订单管理、评论管理、审核外来人员、新…

【ML-SVM案例学习】案例一:对鸢尾花数据进行SVM分类(附源码)

文章目录前言一、完整源码分步实现1.引入库2.读入数据3.编码数据4.数据分割5.数据SVM分类器构建6.计算模型的准确率/精度7.计算决策函数的结构值以及预测值8.画图总结前言 【ML-SVM案例学习】会有十种SVM案例&#xff0c;供大家用来学习。本章实现SVM鸢尾花数据的分类任务。 一…

PDF能编辑修改吗?教你必备的几种编辑方法

可以把PDF文件编辑修改吗&#xff1f;相信这是很多萌新在刚接触PDF文件时所产生的疑惑&#xff0c;因为在想要改动PDF文件的时候&#xff0c;发现无法直接编辑内容&#xff0c;就会有PDF文件可以编辑吗的疑问了&#xff0c;其实有这种想法非常正常&#xff0c;大家都是经历过的…

【设计模式】单例模式

单例模式属于创建型模式&#xff0c;是最简单的一种设计模式。当一个类在程序中只需要创建唯一全局对象时&#xff08;如网站计数类、日志管理类、线程池类……&#xff09;&#xff0c;就可以使用单例模式。单例模式规定一个类只能创建一个实例&#xff0c;之后不能再创建新的…

Verilog语法

Verilog语法 Verilog简介 Verilog是一种硬件描述语言&#xff0c;以文本形式来描述数字系统硬件的结构和行为的语言&#xff0c;用它可以表示逻辑电路图、逻辑表达式&#xff0c;还可以表示数字逻辑系统所完成的逻辑功能。 Verilog 和 C 的区别&#xff1a; Verilog是硬件描…

Linux篇【5】:Linux 进程概念(二)

目录 3.5、查看进程 3.6、通过系统调用接口获取时实进程的标识符 3.7、通过系统调用接口创建子进程 - fork 初识 3.5、查看进程 [HJMhjmlcc ~]$ clear [HJMhjmlcc ~]$ pwd /home/HJM [HJMhjmlcc ~]$ ls [HJMhjmlcc ~]$ touch mytest.c [HJMhjmlcc ~]$ ls mytest.c [HJMhjml…

G1D16-fraud-SVM

早上复习了一下昨天学的内容&#xff0c;发现这零碎时间用来复习&#xff0c;真的很不错。 但是遇到了一个问题&#xff1a;知识推理和知识挖掘有什么区别&#xff1f; 知识规则挖掘是对知识结构的挖掘&#xff0c;可以针对现有的知识体系&#xff0c; 利用部分规则&#xff0…

[附源码]java毕业设计冷链物流管理系统论文

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Redis数据类型之hash

文章目录hashⅠ. 增删查改Ⅱ. 加法操作Ⅲ. 业务场景1 - 购物车Ⅳ. 业务场景2 - 秒杀Ⅴ. 注意事项提示&#xff1a;以下是本篇文章正文内容&#xff0c;Redis系列学习将会持续更新 hash ● 新的存储需求&#xff1a;对一系列存储的数据进行编组&#xff0c;方便管理&#xff0c;…

基于PHP的Laravel框架实现学生管理系统(1+X Web前端开发中级 例题)——初稿

文章目录 &#x1f4c4;题目要求 &#x1f9e9;说明 &#x1f9e9;效果图 &#x1f4bb;题目代码 &#x1f3af;实现效果 &#x1f4f0;完整答案 &#x1f4c4;题目要求 阅读下列说明、效果图和代码&#xff0c;补全代码&#xff08;1&#xff09;-&#xff08;10&…