2013-10-19 214 views
8

複製者:是枚舉實例「封閉」在枚舉類型的Java?

enum IDs { 
    ID { 

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

    void getId() {} 

    private static void w() {} 
} 

警告發出:

訪問封閉方法瓦特()從所述類型ID由合成存取方法仿真

我明白合成方法 - 我沒有得到的是他們如何發揮枚舉 - 我希望枚舉實例具有我在枚舉中定義的所有私有方法。實例是否真的嵌套類?

回答

3

定義方法的枚舉實例,因爲您的ID在這裏做的是enum類的隱式匿名子類的單例。正常訪問規則適用於子類和枚舉類之間,因此需要綜合訪問器來查看枚舉類的私有特徵。

Java語言規範requires enums to work this way

枚舉常數的可選類體隱式地定義一個匿名類聲明(§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),然後一類的身體解析(classOrInterfaceBody(...))爲匿名類(names.empty),然後將其用作實例創建表達式(NewClass(..., body))中的類主體。您可以按照通過JCNewClass節點的編譯,如果你喜歡,但它足以說,它的javadoc的呢,它的型號:

* A new(...) operation. 

如你所知,有一類身體new操作創建一個匿名類。