2012-07-13 4 views
3

인코딩에 해당하는 열거 형이 있습니다. 열거 형에 인코딩에 대한 반복 값이 없는지 확인해야합니다. 자바에서 중복 된 enum 값을 피하는 방법은 무엇입니까?

public enum EncodingsEnum 
{ 

ISO8859_1("ISO-8859-1",0), ISO8859_2("ISO-8859-2",1), 
    ISO8859_3("ISO-8859-3",2), ISO8859_4("ISO-8859-4",3), 
    ISO8859_5("ISO-8859-5",4), ISO8859_6("ISO-8859-6",5), 
    ISO8859_7("ISO-8859-7",6), ISO8859_8("ISO-8859-8",7), 
    ISO8859_9("ISO-8859-9",8), ISO8859_11("ISO-8859-11",9), 
    ISO8859_13("ISO-8859-13",10),ISO8859_15("ISO-8859-15",11), 
    UTF_8("UTF-8",11); 

    public static final int ENCODINGS_COUNT = EncodingsEnum.values().length; 
    private final String encodingName; 
    private final int encodingNumber; 

    EncodingsEnum(final String encodingName,int encodingNumber) 
    { 
     ReferenceChecker.checkReferenceNotNull(encodingName); 

     this.encodingName = encodingName; 
     this.encodingNumber = encodingNumber; 
    } 

    public static String getEncodingNameByNumber(int number) 
    { 
     for(EncodingsEnum encoding : EncodingsEnum.values()) 
     { 
      if(encoding.encodingNumber == number) 
      { 
       return encoding.getEncodingName(); 
      } 
     } 
     throw new RuntimeException("Encoding with this number isn't supported:" + number); 

    } 

    public static int getEncodingNumberByName(final String name) 
    { 
     for(EncodingsEnum encoding : EncodingsEnum.values()) 
     { 
      if(encoding.encodingName.equals(name)) 
      { 
       return encoding.getEncodingNumber(); 
      } 
     } 
     throw new RuntimeException("Encoding with this name isn't supported:" + name); 
    } 

    public String getEncodingName() 
    { 
     return this.encodingName; 
    } 

    public int getEncodingNumber() 
    { 
     return this.encodingNumber; 
    } 
} 

내가 기존 인코딩 중 하나와 동일한 번호로 인코딩을 만들 수 있습니다 문제, 그래서 내가하는 방법을 잘 모릅니다 exception.But를이 열거 형이 번호로 요소를 포함 확인 던질 필요 그거야. 아무 생각 없어? 고마워.

+0

"기존 인코딩과 동일한 번호로 인코딩 할 수 있습니까?" 컴파일시'EncodingsEnum.java'의 내용은 final입니다. 런타임에 새로운'enum' 상수를 생성 할 수 없습니다. 새로운 상수를 추가하기 전에'Ctrl-f '키를 눌러보십시오. –

+0

숫자로 서수를 단순히 가져 가지 마십시오. 그렇게하면 고유 한 언어로 보장됩니다. –

+0

서문을 사용하는 것은 나쁜 습관이라는 것을 알고 있습니다. –

답변

4

런타임에 확인하지 않아야합니다. 너무 늦었을 것입니다. 열거 형 값을 반복하는 단위 테스트를 추가하고 모두 숫자가 다른지 확인하십시오. 그리고 새로운 버전의 응용 프로그램/라이브러리를 생성하기 전에 항상 단위 테스트를 실행하고 통과하는지 확인하십시오.

@Test 
public void encodingNumbersMustBeUnique() { 
    Set<Integer> numbers = new HashSet<Integer>(); 
    for (EncodingsEnum e : EncodingsEnum.values()) { 
     assertFalse(numbers.contains(e.getEncodingNumber())); 
     numbers.add(e.getEncodingNumber()); 
    } 
} 
+0

"너무 늦다"- 엄청난 낭비. 왜 계속 반복해서 점검해야합니까? – duffymo

1

생성자에서 enum의 encodingNumbers를 반복 할 수 있으며 복제본을 찾으면 예외를 throw 할 수 있습니다. 다음과 같은 것 :

public boolean isPresent(String type){ 
      ClassType[] typeArray = ClassType.values(); 
      for(ClassType cType: typeArray){ 
       if(cType.absoluteName/*this is some private field of the class*/.equalsIgnoreCase(type)){ 
        return true; 
       } 
      } 
      return false; 
     } 

생성자에서 번호와 이름을 할당하기 직전에 위의 확인을하십시오. 검사 결과가 true를 반환하면 예외를 throw합니다.

0

이 코드로 해결되었습니다.

public enum EncodingsEnum { 
    ONE(1), 
    TWO(1); 

    private int number; 

    static { 
     if (!test()) { 
     throw new RuntimeException(); 
     } 
    } 

    private EncodingsEnum(int number) { 
     this.number = number; 
    } 

    public static boolean test() { 
     final Set<Integer> numbers = new HashSet<Integer>(); 

     for (final EncodingsEnum enc : EncodingsEnum.values()) { 
     numbers.add(enc.number); 
     } 

     return numbers.size() == EncodingsEnum.values().length; 
    } 
관련 문제