2013-10-19 4 views
8

재생기 :enum 형식이 java의 열거 형에 "동봉"되어 있습니까?

enum IDs { 
    ID { 

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

    void getId() {} 

    private static void w() {} 
} 

경고 출사 : 유형 ID에서() 승 방법을 둘러싸에

액세스는

난 합성 방법은 이해 합성 접근 방법에 의해 에뮬레이트 내가 얻지 못하는 것은 열거 형 (enum)으로 어떻게 작동하는지입니다. enum 인스턴스가 열거 형에서 정의하는 모든 개인적인 메서드를 가질 것으로 기대합니다. 인스턴스가 실제로 중첩 클래스입니까?

답변

3

여기서 ID에서와 같이 메서드를 정의하는 enum 인스턴스는 열거 형 클래스의 암시 적 익명 하위 클래스의 싱글 톤입니다. 일반적인 액세스 규칙은 하위 클래스와 열거 형 클래스 사이에 적용되므로 열거 형 클래스의 비공개 기능을 보려면 합성 접근자가 필요합니다.

Java 언어 사양 requires enums to work this way :

상수 열거의 옵션 클래스 본문이 암시 적으로 익명의 클래스 선언을 정의 (§15.9.5)를 직접 둘러싸는 열거 형을 연장. 클래스 몸체는 익명 클래스의 일반적인 규칙에 의해 규율됩니다 ...

확실히 구현 된 방법입니다. 의 JDK의 javac의에서, 이것은 (이 버전에서) 라인 3344 주위에 JavacParser::enumeratorDeclaration에 발생합니다 선언에서 왼쪽 중괄호 (LBRACE)가있는 경우

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); 

관련 비트

는 다음 클래스 본문이됩니다 익명 클래스 ( names.empty)에 대해 구문 분석 된 ( classOrInterfaceBody(...)) 다음 인스턴스 생성 식 ( NewClass(..., body))에서 클래스 본문으로 사용됩니다. 만약 당신이 좋아하면 당신은 JCNewClass 노드의 편집을 통해 따를 수 있지만 javadoc는이처럼이 말을 충분, 그것이 모델 :

* A new(...) operation. 

을 그리고 당신도 알다시피, 클래스 시체와 함께 new 작업은 익명을 만듭니다 수업.