我编写了一个简单的 Java 字节码解析器来做一些实验,最近它在一个意想不到的地方失败了。java/lang/reflect/Member.java从 Java 1.1.8.16读取时rt.jar,我的解析器发疯了,因为Member开始时是这样的(注意缺少的ACC_ABSTRACT标志):
Classfile Member.class
Last modified Aug 8, 2002; size 350 bytes
MD5 checksum 9a1aaec8e70e9a2ff9d63331cb0ea34e
Compiled from "Member.java"
public interface java.lang.reflect.Member
minor version: 3
major version: 45
flags: (0x0201) ACC_PUBLIC, ACC_INTERFACE
...
Java 1.2.2.17 的版本更正了这一点,并将标志设置为0x0601( ACC_ABSTRACT | ACC_INTERFACE | ACC_PUBLIC)。
我能找到的最早的 JVM 规范(据称是 1.0.2)有这样的说法(§4.1,第 86 页,强调添加):
接口是隐式抽象的(§2.13.1);它
ACC_ABSTRACT的标志必须被设置。接口不能是最终的;如果是这样,它的实现将永远无法完成(第 2.13.1 节),因此它不能ACC_FINAL设置其标志。
JVM 规范的第 9 版有类似的话要说:
如果设置了标志
ACC_INTERFACE,则ACC_ABSTRACT标志也必须设置,并且不能设置ACC_FINAL、ACC_SUPER、ACC_ENUM和ACC_MODULE标志集。
Oracle/Sun JVM 是否强制执行“必须”这样的要求?如果有,从什么时候开始?如果不是,为什么 JVM 规范还要假装它是必需的?