如何看懂Java字节码
1. 字节码基础概念
- 什么是字节码:Java 源代码(
.java)编译后生成的中间代码(.class),由 JVM 执行。 - 文件结构:遵循 JVM 规范,包含魔数、版本号、常量池、类信息、方法表等。
- 指令集:基于栈的虚拟机指令,例如
iload(加载整型)、invokevirtual(调用方法)等。
2. 工具准备
查看字节码的常用工具
javap(JDK 自带):1
javap -c -v YourClass.class # 反编译并显示详细字节码
-c:输出指令码。-v:显示附加信息(常量池、行号表等)。
IDE 插件:
- IntelliJ IDEA:安装
Bytecode Viewer插件(右键类文件 → View → Show Bytecode)。 - Eclipse:使用
Bytecode Outline插件。
- IntelliJ IDEA:安装
图形化工具:
3. 字节码文件结构
关键组成部分
- 魔数(Magic Number):前 4 字节为
0xCAFEBABE,标识为 Java 类文件。 - 版本号:主版本(Major Version)和次版本(Minor Version),例如 Java 8 的主版本号为
52。 - 常量池(Constant Pool):
- 存储类名、方法名、字符串字面量等符号引用。
- 通过索引(如
#1,#2)在指令中引用。
- 访问标志(Access Flags):类的修饰符(
public,final等)。 - 类信息:父类、接口列表。
- 字段表(Fields):类中定义的字段。
- 方法表(Methods):每个方法的字节码、异常表、本地变量表等。
- 属性表(Attributes):附加信息(如源码文件名、行号表)。
4. 理解字节码指令
常见指令示例
- 加载/存储:
aload_0:加载this到操作数栈。iload_1:加载局部变量槽 1 的整型值。
- 算术运算:
iadd:整型加法。fsub:浮点减法。
- 方法调用:
invokevirtual:调用实例方法。invokestatic:调用静态方法。
- 控制流:
ifeq:如果栈顶值为 0,跳转。goto:无条件跳转。
- 对象操作:
new:创建对象。putfield:设置对象字段的值。
Java 字节码文件的分析和对应的 Java 代码还原:
1 | // class version 61.0 (61) |
字节码分析概览
类信息
- 类名:
com.mozi.Main - 版本:Java 17(主版本号
61对应 JDK 17) - 方法:构造函数
<init>和main方法。
1. 构造函数 <init>
字节码
1 | public <init>()V |
作用:调用父类
Object的构造函数。对应 Java 代码
1
2
3
4
5public class Main {
public Main() {
super(); // 调用 Object 的构造函数
}
}
2. main 方法
字节码关键步骤
1 | public static main([Ljava/lang/String;)V |
对应 Java 代码
1 | import java.util.Arrays; |
关键字节码指令解析
ANEWARRAY- 创建引用类型数组(这里是
String[]),长度为栈顶值2。 - 操作后栈状态:
[array_ref]
- 创建引用类型数组(这里是
DUP- 复制栈顶的数组引用,用于多次填充数组元素。
- 操作后栈状态:
[array_ref, array_ref]
AASTORE- 将值存储到数组中,需要三个操作数:
array_ref,index,value。 - 例如:
DUP → ICONST_0 → LDC "add" → AASTORE对应array[0] = "add"。
- 将值存储到数组中,需要三个操作数:
CHECKCAST- 确保从迭代器获取的对象是
String类型,否则抛出ClassCastException。
- 确保从迭代器获取的对象是
FRAME- 指示 JVM 栈帧的变化(如局部变量和操作数栈的更新),调试信息的一部分。
局部变量表
| 索引 | 变量名 | 类型 | 作用域 |
|---|---|---|---|
| 0 | args |
String[] |
整个方法 |
| 1 | list |
List<String> |
L1 到 L6 |
| 2 | iterator |
Iterator |
L2 到 L3 |
| 3 | s |
String |
循环体内 (L4-L5) |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Moziの个人博客!
评论
