我在这里看到编辑 java 字节码有错误,当用 Krakatau 编辑 java 字节码时,它可能会在堆栈帧上发生错误。
那里的答案是将 Krakatau 版本更改为 50。
如果我只想编辑 java 字节码(更改现有方法),是否有任何理由计算堆栈帧而不使用不需要计算的版本 50?
当我
.stack same修复错误时,为什么?版本 50 是 Krakatau 的版本吗?这个版本有什么缺点吗?
感谢
我在这里看到编辑 java 字节码有错误,当用 Krakatau 编辑 java 字节码时,它可能会在堆栈帧上发生错误。
那里的答案是将 Krakatau 版本更改为 50。
如果我只想编辑 java 字节码(更改现有方法),是否有任何理由计算堆栈帧而不使用不需要计算的版本 50?
当我.stack same修复错误时,为什么?
版本 50 是 Krakatau 的版本吗?这个版本有什么缺点吗?
感谢
堆栈映射是 Java 6(对应于 50 版)中添加的一项功能,但直到 Java 7(51 版)才成为强制性要求,以简化转换。堆栈映射使类加载速度稍快,但代价是使字节码生成变得更加痛苦。
如果是手动编辑字节码,那么自己写栈帧是个大麻烦。最简单的解决方案是将您的类文件标记为版本 <= 50,在这种情况下,您根本不必担心它们。唯一的缺点是您不能使用在 51+ 版本中添加的功能(目前,51+ 独有的唯一值得注意的功能是invokedynamic和模块)。
另一方面,有一个功能,子程序,它实际上在版本 50 中被删除了。因此,如果您不指定,Krakatau 会将您的类文件默认为版本 49,因为它是手动编辑字节码的最佳默认版本。
如果您需要使用invokedynamic,那么您别无选择,只能生成堆栈图。如果你愿意,你可以手写它们,但这样做很痛苦。如果您打算这样做,您应该熟悉JVM 规范,它解释了如何编写堆栈映射。Krakatau 的语法使用与规范相同的名称,所以它应该是不言自明的。
或者,您可以使用 ObjectwebASM 之类的工具为您完成。唯一的缺点是 ASM 无法处理某些异常情况。ASM 是一个对于普通用途“足够好”的工具,而 Krakatau 是为高级用户设计的,它试图处理每一个字节码功能和怪癖,无论多么晦涩。但由于堆栈帧不能在 100% 的情况下自动生成,而且 Krakatau 面向那些无论如何都希望对字节码进行低级别控制的人,因此它不会尝试自动生成堆栈帧。
无论如何,要明确回答您的问题,
invokedynamic, 或其他最近添加的字节码功能。.stack same并不总是有效。如果您想了解如何编写堆栈映射,请参阅 JVM 规范。