什么是 JVM 字节码?Java 类文件详解

JVM 字节码是 Java 虚拟机运行的紧凑指令集。 了解 .class 文件的运作方式,以及 mod 为什么会重写字节码,以及 ASM 在其中的作用.

Conceptsby trqUpdated June 4, 2026
Key takeaways
  • JVM 字节码是 Java 虚拟机执行的紧凑指令集。
  • Java 编译器生成 .class 文件中的字节码,而不是本地机器码。
  • 相同的 .class 文件可以在任何安装了 Java 运行环境的平台上运行,这正是该格式的意义所在。
  • 模组通过重写字节码来修改编译后的游戏,而无需访问其源代码.

JVM 字节码是 Java 虚拟机执行的指令集。当您编译 Java 源代码时,编译器不会为您的 CPU 生成机器码,而是生成字节码,这是一种紧凑、可移植的格式,存储在 .class 文件中。JVM 在运行时读取这些指令,并将其转换为本地代码.

Opal 的适用范围

Opal 是一个 Fabric 模组,它所依赖的模组工具会为您完成字节码的工作,因此您无需手动操作助记符。 如果您想使用纯 JavaScript 添加行为,请参阅 脚本介绍

源代码如何转换为字节码

一个 .java 文件是人编写的文本。一个 .class 文件是 JVM 运行的编译输出。编译器读取你的源代码,进行检查,并为每个类写入一个 .class 文件,每个文件包含字节码指令、常量池、方法表和其他元数据。

字节码不绑定到任何特定的处理器。相同的 .class 文件可以在 Windows、macOS、Linux 或任何具有 Java 运行时环境的系统上运行,因为 JVM 是知道如何在本地机器上执行指令的层。这种可移植性是该格式的整个意义所在。

指令是什么样的

字节码是一种基于堆栈的指令集。大多数操作将值压入操作数堆栈,然后弹出它们,并压入一个结果。没有寄存器分配需要考虑;模型是故意简单的,以便 JVM 可以快速验证和执行它。

以下是一些示例操作码,可以让你了解一下:

操作码它做什么
iload将一个 int 局部变量压入堆栈
iadd弹出两个 int,压入它们的和
invokevirtual调用一个实例方法
getfield读取一个实例字段
return从方法返回

你很少手动读取或写入这些操作码。工具会生成和使用它们,而像 ASM 这样的库就派上用场了。

为什么字节码对模组很重要

字节码很重要,因为它允许你在不改变原始源代码的情况下修改行为。一个“我的世界”(Minecraft)模组几乎从不拥有游戏的源代码。它所拥有的只是磁盘上的编译游戏。为了添加或修改功能,模组会读取现有的字节码,重写它,并将结果反馈给 JVM,作为类加载的一部分。

这就是修补框架如何在它们不拥有的方法中插入钩子的方式。它们找到编译方法中的正确位置,并插入对模组代码的调用。在字节码级别工作意味着模组可以附加到游戏,即使它从未见过任何原始 Java 代码的一行。

ASM 的作用

ASM 是一个用于读取、写入和转换字节码的 Java 库。它将 .class 文件解析为事件或树,允许代码修改指令,并发出一个有效的 .class 文件。它体积小巧、速度快,并且与原始格式紧密相关,这就是为什么更高级的模组工具会在此之上构建,而不是自行解析类文件。

大多数模组开发者很少直接调用 ASM。他们使用一个更高级的层,该层隐藏了操作码,并提供了一种更友好的方式来表达“在方法开始时运行我的代码”。底层,该层正在编辑字节码,通常通过 ASM。

常见问题解答