深入拆解 Java 虚拟机
郑雨迪
Oracle 高级研究员,计算机博士
88841 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 44 讲
模块四:黑科技 (3讲)
深入拆解 Java 虚拟机
15
15
1.0x
00:00/00:00
登录|注册

如何使用Class-File API编辑Java字节码?

你好,我是郑雨迪。
关注 JDK 进展的同学们可能知道,Class-File API 是 JDK 22 引入的预览特性 [1]。它与 ASM [2]、BCEL [3]和 Javassist [4] 类似,都是用于分析、生成和修改 Java 字节码的工具。经过两个版本的迭代,这一 API 终于在 JDK 24 中正式发布。
这时,有人可能会疑惑:既然 JDK 已经内置了 ASM [5],为什么还要额外开发一个新的轮子? 要回答这个问题,就必须了解 JDK 版本的更新机制以及字节码编辑工具的演进方式。
每当 JDK 版本升级,生成的类文件都会随之更新版本号,以便区分不同版本。例如,下面是 Foo.java 生成的字节码,其中,偏移量 6 处的两个字节表示该类文件的主版本号。在 JDK 23 中,这两个字节的值为 0x0043(Java 类文件采用 Big Endian 存储),而在 JDK 24 中,它变为 0x0044。
$ cat Foo.java
public class Foo {
}
$ jdk23/bin/javac Foo.java
$ xxd Foo.class
00000000: cafe babe 0000 0043 000d 0a00 0200 0307 .......C........
00000010: 0004 0c00 0500 0601 0010 6a61 7661 2f6c ..........java/l
00000020: 616e 672f 4f62 6a65 6374 0100 063c 696e ang/Object...<in
00000030: 6974 3e01 0003 2829 5607 0008 0100 0346 it>...()V......F
00000040: 6f6f 0100 0443 6f64 6501 000f 4c69 6e65 oo...Code...Line
00000050: 4e75 6d62 6572 5461 626c 6501 000a 536f NumberTable...So
00000060: 7572 6365 4669 6c65 0100 0846 6f6f 2e6a urceFile...Foo.j
00000070: 6176 6100 2100 0700 0200 0000 0000 0100 ava.!...........
00000080: 0100 0500 0600 0100 0900 0000 1d00 0100 ................
00000090: 0100 0000 052a b700 01b1 0000 0001 000a .....*..........
000000a0: 0000 0006 0001 0000 0001 0001 000b 0000 ................
000000b0: 0002 000c ....
$ jdk24/bin/javac Foo.java
$ xxd Foo.class
00000000: cafe babe 0000 0044 000d 0a00 0200 0307 .......D........
00000010: 0004 0c00 0500 0601 0010 6a61 7661 2f6c ..........java/l
00000020: 616e 672f 4f62 6a65 6374 0100 063c 696e ang/Object...<in
00000030: 6974 3e01 0003 2829 5607 0008 0100 0346 it>...()V......F
00000040: 6f6f 0100 0443 6f64 6501 000f 4c69 6e65 oo...Code...Line
00000050: 4e75 6d62 6572 5461 626c 6501 000a 536f NumberTable...So
00000060: 7572 6365 4669 6c65 0100 0846 6f6f 2e6a urceFile...Foo.j
00000070: 6176 6100 2100 0700 0200 0000 0000 0100 ava.!...........
00000080: 0100 0500 0600 0100 0900 0000 1d00 0100 ................
00000090: 0100 0000 052a b700 01b1 0000 0001 000a .....*..........
000000a0: 0000 0006 0001 0000 0001 0001 000b 0000 ................
000000b0: 0002 000c ....
由于新版本的 JDK 可能引入新的类文件格式,字节码编辑工具通常会维护一个支持的版本范围。当遇到超出支持范围的类文件时,这些工具往往会直接报错,以防止解析错误导致生成不合法的类文件。
为了减少因 JDK 版本间开发导致的 API 变更,字节码编辑工具通常会等到某一 JDK 版本正式发布后才开始适配新版本。如果 JDK 的更新涉及较大的字节码变更,这些工具的兼容性开发可能会持续数月。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
  • 解释
  • 总结

1. JDK 22 引入了 Class-File API,旨在与类文件格式同步演进,使得依赖它的其他组件能够自动适配最新的类文件格式,从而让新的语言特性和 JVM 特性能够被更快速、更便捷地采用。 2. Class-File API 提供了 ClassModel、FieldModel、MethodModel 和 CodeModel 等模型,以及构建器和转换器,用于创建新的类文件结构和描述字节码的修改过程。 3. 该 API 可以用于解析、生成和修改 Java 字节码,为字节码编辑工具的开发提供了更便捷的方式。 4. Class-File API 的引入可以帮助应用和框架更快速地适配最新的类文件格式,以应对 JDK 版本升级后的兼容性和稳定性问题。 5. Class-File API 的设计围绕两个关键词展开:抽象与效率。它屏蔽了类文件中的底层细节,如常量池等,将用户真正关心的内容抽象为不可变对象,并以树状结构组织起来。这种设计不仅让操作更直观,还提升了可读性和可靠性。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解 Java 虚拟机》
新⼈⾸单¥59
立即购买
登录 后留言

精选留言

由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论
显示
设置
留言
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部