いくつかの実験を行うために単純な 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、p. 86、強調を追加)。
インターフェイスは暗黙のうちに抽象的です (§2.13.1)。その
ACC_ABSTRACT
フラグを設定する必要があります。インターフェイスを final にすることはできません。もしそうなら、その実装は決して完了できません (§2.13.1) ので、そのフラグをACC_FINAL
設定することはできませんでした。
JVM 仕様のバージョン 9 には、次のような言葉があります。
ACC_INTERFACE
フラグが設定されている場合は、ACC_ABSTRACT
フラグも設定する必要があり、ACC_FINAL
、ACC_SUPER
、ACC_ENUM
、およびACC_MODULE
フラグ セットを設定してはなりません。
Oracle/Sun JVM は、「そうでなければならない」というこの要件を強制しますか? もしそうなら、いつからですか?そうでない場合、なぜ JVM 仕様はわざわざそれが必要であるかのように振る舞うのでしょうか?