为什么Java 1.0.2中的接口成员没有ACC_抽象集?

为什么Java 1.0.2中的接口成员没有ACC_抽象集?,java,jvm,bytecode,.class-file,jvm-bytecode,Java,Jvm,Bytecode,.class File,Jvm Bytecode,我已经编写了一个简单的Java字节码解析器来做一些实验,最近它在一个意想不到的地方失败了。当从java 1.1.8.16的rt.jar中读取java/lang/reflect/Member.java时,我的解析器发疯了,因为Member一开始就是这样(注意缺少ACC\u ABSTRACT标志): Java 1.2.2.17版本纠正了这一点,并将标志设置为0x0601(ACC_ABSTRACT | ACC_INTERFACE | ACC_PUBLIC) 我能找到的最早的JVM规范(据称是1.0.2

我已经编写了一个简单的Java字节码解析器来做一些实验,最近它在一个意想不到的地方失败了。当从java 1.1.8.16的
rt.jar
中读取
java/lang/reflect/Member.java
时,我的解析器发疯了,因为
Member
一开始就是这样(注意缺少
ACC\u ABSTRACT
标志):

Java 1.2.2.17版本纠正了这一点,并将标志设置为
0x0601
ACC_ABSTRACT | ACC_INTERFACE | ACC_PUBLIC

我能找到的最早的JVM规范(据称是1.0.2)是这样说的(§4.1,第86页,重点补充):

接口是隐式抽象的(§2.13.1);必须设置其
ACC\u ABSTRACT
flag。接口不能是最终的;如果是的话,它的实施永远无法完成(§2.13.1),因此它不能设置其
ACC_FINAL
fl ag

JVM规范的第9版:

如果设置了
ACC_接口
标志,则还必须设置
ACC_抽象
标志
,并且不得设置
ACC_最终
ACC_超级
ACC_枚举
ACC_模块
标志集

Oracle/Sun JVM是否强制执行“必须”这样的要求?如果是,从什么时候开始?如果不是,为什么JVM规范要假装它是必需的呢?

我不清楚为什么,但我尝试创建以下类, 使用Java 9的
javac
编译它们,然后在
Foo
中手动编辑
access_标志
0x200
;然后通过不同的Java版本手动循环
minor\u version
major\u version
,查看会发生什么:

interface Foo { }

class Bar implements Foo {
    public static void main(String[] args) {
        System.out.println("BAZ");
    }
}
结果:

╭──────╥───────┬───────┬─────╮
│ Java ║ minor │ major │ out │
╞══════╬═══════╪═══════╪═════╡
│  1.1 ║    03 │    2d │ BAZ │
│  1.2 ║     " │     " │ BAZ │
│  1.3 ║     " │    2e │ BAZ │
│  1.4 ║    00 │    2f │ BAZ │
│   5  ║    00 │    31 │ BAZ │
│   6  ║    00 │    32 │ err │
│   7  ║    00 │    33 │ err │
│   8  ║    00 │    34 │ err │
│   9  ║    00 │    35 │ err │
└──────╨───────┴───────┴─────┘
其中“err”实际上是这样打印出来的:

Error: LinkageError occurred while loading main class Bar
    java.lang.ClassFormatError: Illegal class modifiers in class Foo: 0x200
所以我想他们终于开始在Java6中实施它了

仍然不确定原因。

这是一个错误:javac没有为接口设置
ACC\u ABSTRACT

该错误在1.2中得到了修复,但由于已经有许多类使用该错误编译,JVM获得了一种变通方法,可以为所有使用
ACC\u接口的类自动添加
ACC\u ABSTRACT
。这一直有效,直到Java6最终决定严格遵循新类文件的规范。但是,要向后兼容较旧版本的类文件,解决方法到目前为止仍然存在,请参阅:

if((标志和JVM\u ACC\u接口)和&u主版本
谢谢@apangin。非常感谢您通过与源材料的两个链接来解开我的谜团!
Error: LinkageError occurred while loading main class Bar
    java.lang.ClassFormatError: Illegal class modifiers in class Foo: 0x200
    if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) {
      // Set abstract bit for old class files for backward compatibility
      flags |= JVM_ACC_ABSTRACT;
    }