什么是 ASM(Java 字节码)?库详解

ASM 是一個在執行時讀取和寫入 JVM 字節碼的 Java 庫。以下是其功能、工作原理以及為什麼 Minecraft 模組依賴它的原因.

Librariesby trqUpdated June 4, 2026
Key takeaways
  • ASM 是一个用于读取、修改和写入 JVM 字节码的 Java 库。
  • 它作用于编译后的 .class 文件,因此可以在不重新编译的情况下重写一个类。
  • 模组使用它在加载时修补已经编译的游戏。
  • 大多数模组制作者使用 Mixin,它位于 ASM 之上并隐藏了细节.

ASM 是一个用于读取、修改和写入 JVM 字节码的 Java 库。它直接操作编译后的 .class 文件,而不是源代码,因此可以在不重新编译的情况下检查或重写类。Minecraft 模组依赖于它,因为它允许在游戏加载时对其进行补丁修改,即使游戏已经编译完成.

Opal 的适配方式

Opal 是一个 Fabric 模组,而 Fabric 模组通过这个字节码层深入游戏代码。您无需直接触碰它:脚本引擎 为您提供了一种干净的方式来扩展 Opal,而无需编写字节码。

ASM 实际上做什么

ASM 将编译后的类转换为程序可以编辑的内容。一个 .class 文件仅仅是字节码,即 Java 虚拟机运行的指令。ASM 解析这些字节码,将方法和字段交给您,并允许您添加、删除或更改指令。然后,它将一个新的有效类写回。

纯粹的 Java 本身无法做到这一点。编译器将您的源代码编译成字节码一次,之后字节码就被固定了。ASM 在字节码层面上进行干预,这位于您通常编写的源代码层之下

它是如何运作的

ASM 使用 ClassReader 读取一个类,并使用 ClassWriter 写入一个类。 在两者之间,你的代码会访问类的各个部分并决定需要更改什么。 有两种方法可以做到这一点。

Visitor 模式会逐个元素地流式处理类。 这种方法速度快且内存占用少,因为它从不一次性持有整个类。 树模式将类加载到你可以自由地遍历和编辑的对象中,这对于较大的更改来说更容易理解,但会占用更多内存。

方式工作原理适用场景
Visitor API读取时流式处理类事件小而快速的编辑,内存占用低
Tree API构建类的可编辑对象模型更大或更复杂的重写

为什么 Minecraft 他们使用它

模组需要修改他们没有编写且无法重新编译的游戏代码。游戏以编译后的类形式发布,因此唯一的入口点是字节码级别,而 ASM 正好提供了这一点。一个模组可以在游戏方法中注入钩子,重定向调用,或添加字段,所有这些都在启动时完成。

大多数模组制作者不会直接调用 ASM。他们使用 Mixin,这是一个更高级的框架,它建立在 ASM 之上,并将简单的注解转换为底层的字节码修改。你只需要编写一个小的 Java 类来描述更改,框架就会为你处理使用 ASM 的底层工作。特别是 Fabric 模组,尤其依赖于这个链条。

何时需要直接接触 ASM

作为模组作者,你很少需要编写原始的 ASM 代码。它通常出现在工具需要比注解更多的控制权时,例如加载器、混淆器或重写整个类的补丁程序。对于日常模组来说,顶层的注解层就足够了,而且出错的可能性要小得多。

常见问题解答