ここで行うように、メソッドを定義する列挙型インスタンスID
は、列挙型クラスの暗黙の匿名サブクラスのシングルトンです。サブクラスと列挙型クラスの間には通常のアクセス ルールが適用されるため、列挙型クラスのプライベート機能を表示するには合成アクセサーが必要です。
Java 言語仕様では、列挙型が次のように機能する必要があります。
列挙型定数のオプションのクラス本体は、直接囲んでいる列挙型を拡張する匿名クラス宣言 (§15.9.5) を暗黙的に定義します。クラス本体は、匿名クラスの通常の規則によって管理されます...
それは確かにそれらが実際にどのように実装されているかです。JDK の javac では、これはJavacParser::enumeratorDeclaration
3344 行目あたりで発生します (このバージョンでは)。
JCClassDecl body = null;
if (token.kind == LBRACE) {
JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
List<JCTree> defs = classOrInterfaceBody(names.empty, false);
body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
}
if (args.isEmpty() && body == null)
createPos = identPos;
JCIdent ident = F.at(identPos).Ident(enumName);
JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
関連するビットは、宣言に左中括弧 ( ) がある場合、匿名クラス ( )LBRACE
のクラス本体が解析され ( ) 、これがインスタンス作成式でクラス本体として使用される ( )ことです。 . 必要に応じてノードのコンパイルをたどることができますが、その javadoc と同様に、次のようにモデル化するだけで十分です。classOrInterfaceBody(...)
names.empty
NewClass(..., body)
JCNewClass
* A new(...) operation.
ご存知のようにnew
、クラス本体を操作すると匿名クラスが作成されます。