一文讲清楚JVM字节码文件的组成

01-以正确的姿势打开文件

字节码文件中保存了 源代码编译之后的内容,以 二进制的方式 存储,无法直接用记事本打开阅读

通过NotePad++使用十六进制插件查看class文件:

推荐使用 jclasslib 工具查看字节码文件;
Github地址: https://github.com/ingokegel/jclasslib

02-字节码文件的组成

字节码文件总共可以分为以下几个部分:

  • 基础信息 :魔数、字节码文件对应的 Java版本号、访问标识(public final 等)、父类和接口信息
  • 常量池: 保存了 字符串常量、类或接口名、字段名,主要在字节码指令中使用
  • 字段: 当前类或接口声明的 字段信息
  • 方法: 当前类或接口声明的方法信息,核心内容为方法的字节码指令
  • 属性: 类的属性,比如源码的文件名、内部类的列表等

2.1 基本信息

基本信息包含了jclasslib中能看到的两块内容:一般信息 和 接口

01-魔数

02-主副版本号

03-其它基础信息

2.2 常量池

字节码文件中常量池的作用:避免相同的内容重复定义,节省空间

本质是一个数组

2.3 方法

通过分析方法的字节码指令,可以清楚地了解一个方法到底是如何执行的。先来看如下案例:

java 复制代码
int i = 0;
int j = i + 1;

这段代码编译成字节码指令之后是如下内容:

关于三条字节码指令的说明:

  • iconst_常量值:将 该常量放入操作数栈 中;
  • istore_数组下标:将 操作数栈中的值 放到 局部变量表对应的数组下标 中;
  • iload_数组下标:将 局部变量表中对应数组下标的值取出来放到操作数栈 中

01-操作数栈 & 局部变量表

要理解这段字节码指令是如何执行的,我们需要先理解两块内存区域:操作数栈和局部变量表。

  • 操作数栈 是用来存放临时数据的内容,是一个栈式的结构,先进后出;
  • 局部变量表 是存放方法中的局部变量,包含方法的参数、方法中定义的局部变量,在编译期就已经可以确定方法有多少个局部变量

02- i = i++ 的执行流程

i++ 的字节码指令如下:

  • 其中 iinc 1 by 1 指令指的是 将局部变量表1号位置增加1,其实就实现了i++的操作

最终结果仍为 0

03- i = ++i 的执行流程

而 ++i 只是对两个字节码指令的顺序进行了更改:iioad_1 和 iinc 1 by 1

最终结果为 1

04-经典面试题

05-思考

i++:iinc 1 by 1;
k+=1:iinc 2 by 1

i++ 和 k+=1 都是一行 iinc _ by 1 就搞定了,但是 j = j + 1 需要四行指令

相关推荐
萧瑟余晖2 小时前
Spring Batch核心模型与快速上手详解
java·spring·batch
缓慢更新2 小时前
AI 辅助生成单测:从接口定义到用例的流水线
java·服务器·前端·网络·数据库·人工智能
LMT流氓兔4 小时前
第五单元——第十六课:给书店助手加上网页界面
java·开发语言·jvm·人工智能·oracle·langchain·1024程序员节
wangbing11255 小时前
平台介绍-modbus设备调试
java
西索斯coding5 小时前
gpt-image-2.5-sunburst 和 gemini-3.1-flash-image 差多少?60 组项目素材的成功成本评测框架
java·linux·gpt·ai
wuminyu6 小时前
Java字节码学习总结:字节码如何加载、解析和执行
java·linux·c语言·jvm·c++
Flynn Liang6 小时前
大模型怎么自己调函数?Spring AI 2.0 Tool Calling 自动循环原理 + 完整时序图
java·人工智能·spring·agent·函数调用·springai·toolcalling
乌暮7 小时前
请求进门先安检:Spring 拦截器与统一功能实战指南
java·开发语言·后端·学习·spring
学长毕设7 小时前
基于SpringBoot的烘焙商品商品系统-附源码
java·spring boot·后端
金銀銅鐵8 小时前
[Java] 用纯 Swing 做一个《論語·學而》阅读器
java·ai编程·交互设计