2013-10-19 8 views
8

再生:放出されたenum型はjavaの列挙型に「囲まれていますか?

enum IDs { 
    ID { 

     @Override 
     void getId() { 
      w(); // warning here 
     } 
    }; 

    void getId() {} 

    private static void w() {} 
} 

警告:

タイプIDから(Wメソッドを囲むへのアクセスは)私は合成法が何であるかを理解する合成アクセサ方法

によってエミュレートされます私が何を得ていないかは、列挙型でどのように動作するかです。列挙型で定義するすべてのプライベートメソッドをenumインスタンスに期待します。インスタンスは実際にネストされたクラスですか?

答えて

3

メソッドを定義するenumインスタンスは、IDのように、enumクラスの暗黙の匿名サブクラスのシングルトンです。通常のアクセス規則はサブクラスとenumクラスの間で適用されるため、enumクラスのプライベート機能を見るには合成アクセサが必要です。

Java言語仕様requires enums to work this way:enum定数の

オプションクラス本体は、暗黙的に直接囲む列挙型を拡張する匿名のクラス宣言(§15.9.5)を定義します。クラス本体は、通常の匿名クラスの規則に従います。

実際に実装されている方法は間違いありません。 JDKのjavacのでは、これは、(このバージョンで)線3344の周りJavacParser::enumeratorDeclarationで起こる:

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)がある場合、そのクラスの本体であることがあります匿名クラス(names.empty)の解析済み(classOrInterfaceBody(...))であり、インスタンス作成式(NewClass(..., body))のクラス本体として使用されます。

* A new(...) operation. 

そして、あなたが知っているように、クラスのボディを持つnew操作が匿名を作成します。それのモデルということ、あなたが好きな場合は、JCNewClassノードのコンパイルフォロースルーすることができますが、そのjavadocはないとして、それは、言っていればよいですクラス。

関連する問題