2011-10-05 4 views
11

일부 열거 형의 enum.valueof 메서드를 다시 구현하여 더 이상 예외를 throw하지 않도록해야합니다. 대신 값이 열거 형에없는 경우 null을 반환합니다.열거 형에서 valueof를 다시 구현하는 방법

나는 기본적인

@Override 
    public static <T extends Enum<T>> T valueOf(Class<T> enumType, 
      String name){ 

노력하고있어하지만 내가 무시하거나 슈퍼 타입을 구현해야 할 말, 작동하지 않습니다.

내가 생각할 수있는 수퍼 클래스를 생각해 낼 수는 있지만이 방법을 모을 방법이 확실하지 않습니다. 어떤 아이디어?

답변

17

수 없습니다. 다른 방법을 정의해야합니다. valueOf 메서드는 컴파일러에서 자동으로 생성됩니다.

public static MyEnum permissiveValueOf(String name) { 
    for (MyEnum e : values()) { 
     if (e.name().equals(name)) { 
      return e; 
     } 
    } 
    return null; 
} 
+0

음, 내가 이런 식으로해야 할 것 같아. 단지 내가 그렇게 많이 바꿀 필요가 없길 바랐다. 감사합니다 – scphantm

+0

왜 자바가 이것을 허용하지 않는지 확실하지 않습니다. 'valueOf'를 오버라이드하는 것은 자신의 구현보다 더 의미가 있으며 귀하의 enum 클라이언트가 귀하의 국제 대회를 배울 필요가 있습니다. –

+0

확실하지는 않지만, 당신의 메소드 구현은 enum이 실제로 추가적인 getName() 메소드를 필요로한다고 생각합니다. 정말 열거 형의 실제 이름을 얻으려면 내장 된'name()'을 사용해야한다고 생각합니다. 참으로 – schneida

0

열거 형 클래스에서 새로운 (변환과 다른 이름) 정적 메서드를 만드는 것이 좋습니다.

public enum MyEnum{ 
     .... 

    public static MyEnum convert(Object value){ 
     ... 
    } 
} 
2

는이 방법이 열거 형은 자동으로이 방법 같은 valueOf라고하는 것이 절대적으로 필요하다? 현재 작업중인 프로젝트에서 비슷한 방법이 있지만이를 다르게 부릅니다.

public static ESomeEnum forName(String name) { 
    for (ESomeEnum e : ESomeEnum.values()) { 
     if (e.name().equals(name)) { 
      return e; 
     } 
    } 

    return null; 
} 
+1

XML 바인딩의 일부인 수십 개의 다른 클래스에서 참조되기 때문에 valueOf라고 부르기 바 랍니다. valueof를 재정의 할 수 있다면 바인딩을 전혀 변경할 필요가 없으며 기본적으로 내 메서드를 사용합니다. 그러나 새로운 방법을 만들어야한다면 수십 개의 바인딩을 업데이트해야합니다. 내가 결국해야만했던 것이 무엇인지. – scphantm

8

사용 아파치 코 몬즈 랭 : 다음 Javadoc for EnumUtils.getEnum에서

MyEnum myEnum = EnumUtils.getEnum(MyEnum.class, "MY_ENUM_VALUE"); 

인용구 : 예, forName에 대한 발견되지 않는 경우는

는 null를 돌려 클래스의 열거를 가져옵니다. 그것이 잘못된 열거 이름에 대한 예외가 발생하지 않는다는 점에서

이 방법은 Enum.valueOf (java.lang.Class의, java.lang.String의) 다릅니다.

+0

좋은 답변입니다. 우리가 원하는대로 Java를 작동시키기 위해 추가 라이브러리가 필요 하다니 ... – Betlista

2

valueOf를 재정의 할 필요가 없습니다. 다음은 내가 한 일입니다.

일부 문자열을 열거 형으로 구문 분석해야하며 선언문 이름과 일치하지 않으므로 valueOf(String name)의 재 구현을 수행했습니다.

public enum Command { 
    DIR("DIR"), 
    PUT("PUT"), 
    GET("GET"), 
    OK("OK"), 
    ERROR("ERROR"), 
    READY("READY"), 
    FIN("#FIN#"); 

    private String name; 

    private Command(final String name) { 
     this.name = name; 
    } 

    /** 
    * Returns the desired Enum or throws an exception 
    * @param commandName - String with the name contained by the Enum that you want 
    * @return Command 
    */ 
    public static Command getEnum(String commandName){ 
     // if the string is "#FIN#" returns Command.FIN. 
     if(FIN.toString().equals(commandName)){ 
      return FIN; 
     } 
     // if the name matches any of the remaining enums return whichever one matches 
     else if(Arrays.asList(Command.values()).contains(Command.valueOf(commandName))){ 
      return Command.valueOf(commandName); 
     } 
     // if it still wasn't found, throw an exception 
     throw new IllegalArgumentException("No enum defined for this string: " + commandName); 
    } 

    @Override 
    public String toString(){ 
      return name; 
     } 
    } 

이 코드는 테스트되었으며 작동합니다.

당신은 같이 사용할 수 있습니다

Command k = Command.getEnum("#FIN#"); 
System.out.println(k.name() + " " +k.toString()); 
k = Command.getEnum("PUT"); 
System.out.println(k.name() + " " +k.toString()); 

그리고 출력 될 것입니다 :

FIN #FIN# 
PUT PUT 

는 도움이되기를 바랍니다.

관련 문제