如何将操作码中的 ASM API 版本映射到 Java 版本?



ASM的ClassVisitor构造函数需要传递OpcodesASM4ASM5ASM6ASM7ASM8ASM9之一。

如何知道每个版本的Java使用哪个ASM#?Java 8使用什么ASM#?Java 11使用什么ASM#

ASM…常量描述软件所需的最小ASM库版本。这对于兼容性至关重要,例如在Visitor API中,因为当您覆盖旧版本中不存在的方法时,在链接到旧版本时不会注意到这一点。该方法永远不会被调用。

因此,使用ASM…常量可以更早地发现此类问题。这就是为什么一些实现类提供了一个不需要版本号的构造函数,而子类不允许,而它们的子类构造函数确实需要版本号。因为只有子类可以重写方法,因此,会受到这个问题的影响。

如果您不打算将软件与旧版本的ASM库一起使用,只需使用与当前ASM库版本相对应的编号,即不带EXPERIMENTAL后缀的最高编号。否则,我建议在开发和测试期间使用旧版本,这再次允许只使用该版本中存在的最高ASM…数字。

您可以使用最新的ASM库生成针对所有版本的类。这取决于传递给visit方法的版本。对于Java 8是V1_8,对于Java 11是V11。这些常量的实际值与JVM规范的版本相同。

据我所知,这不是一个简单的方法,但ASM的变更日志帮助很大。请注意,这些版本指的是ASM版本,NOT类文件格式版本。

您似乎需要指定一个支持您拥有的任何类文件的ASM API版本,因此,如果您所在的上下文使用未知的最新ASM,则可以通过反射字段搜索来指定它。

private static int ASM_VERSION = Opcodes.ASM5;      // Default to first Java 8 version
static {
try {
for (int i = 6; true; i++) {                // Loop for as many versions are available
Field asmField = org.objectweb.asm.Opcodes.class.getField("ASM" + i);
ASM_VERSION = asmField.getInt(null);
}
} catch (Throwable exception) {
}
}

然后将其用作:

ClassVisitor cv = new ClassVisitor(ASM_VERSION)

相关内容

最新更新