2010-02-08 2 views
6

유틸리티 클래스의 메서드에 열거 형 값을 전달하고 같은 열거 형의 다른 열거 형 값을 가져 오려고합니다. 이런 식으로 뭔가 : 방법 getEnumAttribute()자바 : 특정 열거 형 및 일반 열거 형 <?> 매개 변수

public class XMLUtils { 

    public static Enum<?> getEnumAttribute(Element element, String name, 
      Enum<?> defaultValue) { 

     if (element.hasAttribute(name)) { 
      String valueName = element.getAttribute(name); 
      // search for value 
      for (Enum<?> value: defaultValue.getClass().getEnumConstants()) 
       if (value.toString().equalsIgnoreCase(valueName)) 
        return value; 
     } 
     // not found, return default value 
     return defaultValue; 
    } 
} 

사용 :

// simple enum 
public enum EUploadMethod { 
    INSERT, UPDATE, DELETE 
} 

// read enum value from XML config file 
EUploadMethod method = XMLUtils.getEnumAttribute(element, "method", 
     EUploadMethod.INSERT); 

이 코드는 완벽하게 작동, 이클립스 컴파일 및 경고 또는 오류없이 실행하고 매력처럼 작동합니다.

하지만 청소하고 Maven2에 의해 명령 행 에서 프로젝트를 컴파일 할 때, 그것은 getEnumAttribute가 호출되는 경우 줄에 오류와 함께 실패합니다

: 나는 이클립스와 메이븐 중 하나에서 일 JDK 1.6를 사용하고

$ mvn clean compile 
.... 
[ERROR] /home/.... DataUploader.java:[173,53] inconvertible types 
found : java.lang.Enum<capture#414 of ?> 
required: .....DataUploader.EUploadMethod 

$ mvn -version 
Apache Maven 2.2.1 (r801777; 2009-08-06 21:16:01+0200) 
Java version: 1.6.0_14 
Java home: /usr/lib/jvm/java-6-sun-1.6.0.14/jre 
Default locale: en_US, platform encoding: UTF-8 
OS name: "linux" version: "2.6.27-17-generic" arch: "i386" Family: "unix" 

질문 :

  1. 이 코드가 컴파일 가능한 이유는 이클립스에서 작동하는이고, 컴파일 할 때까지는 동일한 javac 컴파일러를 사용하는 Maven 이 실패합니다.

  2. 특정 열거 형을 일반 Enum<?> 매개 변수에 전달하면 어떤 문제가 발생합니까? 이 제네릭에 관해서 특히

감사합니다,

마틴 Schayna

+0

maven-2 태그는 maven 관련 문제가 아니고 pure eclipse/javac 컴파일러 문제이므로 제거했습니다. –

+0

Eclipse에는 JDK와 관계없이 자체 컴파일러가 있습니다. 그렇기 때문에 JDK가 설치 될 필요가 없습니다 (JRE 만 필요합니다). – finnw

답변

9
  1. 이클립스 컴파일러와 javac의는 약간의 차이가 있습니다. 일식이 올바른지 생각됩니다,하지만 :)

  2. 문제가 내가 사용하는 이클립스의 버전 모르지만 내가 잘못 생각

    public static <T extends Enum<T>> Enum<T> getEnumAttribute(Element element, String name, 
        Enum<T> defaultValue) { 
        ... 
    } 
    
+0

감사합니다. 당신은 절대적으로 맞습니다! 당신의 대체 메쏘드 서명은 이클립스와 메이븐에서 컴파일 할 수있는 소스입니다. 두 컴파일러의 차이점에 대해 조금 혼란 스럽습니다 ... 어쨌든, 다시 한번 감사드립니다! – mschayna

+2

제약 조건'>'은 맞지만'T'의 추상 수퍼 클래스 인'Enum '이 아닌 반환 형식을'T' (실제 열거 형)로 만들 수 있습니다. – finnw

1

시도하지 않습니다 이리. 제 버전은 Maven에서보고있는 것과 같은 오류를보고합니다. 오류는 진짜 오류입니다.

getEnumAttribute()의 서명에 두 개의 와일드 카드 ("?")가 있지만 문제가 동일하게 적용되도록하는 제약 조건이 없으며 (만들 수도 있습니다) 문제가 있습니다. 따라서 클라이언트는 한 유형의 열거 형을 기본값으로 전달하고 다른 유형의 열거 형을 반환 할 수 있습니다.

당신은 명명 된 형식 매개 변수에 모두 와일드 카드를 대체하여 호출 코드에서 오류를 제거 할 수 있습니다,

class XMLUtils { 

    @SuppressWarnings("unchecked") 
    public static <E extends Enum<E>> E getEnumAttribute(Element element, String name, 
      E defaultValue) { 

     if (element.hasAttribute(name)) { 
      String valueName = element.getAttribute(name); 
      // search for value 
      for (Enum<?> value: defaultValue.getClass().getEnumConstants()) 
       if (value.toString().equalsIgnoreCase(valueName)) 
        return (E) value; 
     } 
     // not found, return default value 
     return defaultValue; 
    } 
} 

그러나 나는 그것이되지 않은 캐스트를 제거 할 수 생각하지 않습니다 Enum<E>.getClass() 반환 Class<Enum<?>> 때문에 그래서 컴파일러는 enumConstants 배열에 어떤 유형의 열거 형이 들어 있는지 알 수 없습니다.

+0

이론적 인 분석, 특히 두 개의 다른 enum 유형 ("defaultValue"와 하나의 결과에 대한 것)에 대한 "바람직하지 않은"허용 오차가 중요합니다. 그러나 제 경우에는 많은 실수를 일으키지 않을 것입니다. 완전성을 위해 : Eclipse 3.5.1을 사용하고 있습니다. – mschayna