2011-10-05 10 views
11

Muszę ponownie wdrożyć enum.valueof metody kilku moich wyliczeń, tak aby nie rzucać wyjątków, zamiast tego po prostu zwracają wartość null, jeśli wartość nie istnieje w wyliczeniu.W jaki sposób ponownie uzupełnić valueof na wyliczenie

Próbuję podstawową

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

ale to nie działa, mówiąc muszę zastąpić lub realizować super typ.

Potrafię wymyślić super klasę, ale nie jestem pewna, jak to połączyć. Jakieś pomysły?

Odpowiedz

17

Nie możesz. Będziesz musiał zdefiniować inną, inną metodę. Metoda valueOf jest automatycznie generowana przez kompilator.

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

Tak, myślę, że będę musiał to zrobić w ten sposób. po prostu liczyłem, że nie będę musiał tak dużo zmieniać. dzięki – scphantm

+0

Tak, nie wiem, dlaczego Java nie pozwala na to. Nadpisywanie "valueOf" byłoby dużo bardziej sensowne niż implementowanie własnego i posiadanie klientów twojego wyliczenia musi nauczyć się twojej konwencji. –

+0

Nie jestem pewien, ale myślę, że twoja implementacja metody faktycznie wymaga enum, aby mieć dodatkową metodę 'getName()'. Myślę, że powinieneś naprawdę używać wbudowanego 'name()', aby uzyskać aktualną nazwę enum. – schneida

0

Możesz rozważyć utworzenie nowej (innej nazwy, takiej jak konwertuj) metody statycznej w swoich klasach wyliczeniowych.

public enum MyEnum{ 
     .... 

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

Czy to absolutnie konieczne, że metoda jest wywoływana valueOf jak metody, które mają automatycznie teksty stałe? W projekcie, nad którym obecnie pracuję, stosujemy podobne metody, ale nazywamy je inaczej; na przykład, forName:

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

    return null; 
} 
+1

Chciałem nazwać go valueOf, ponieważ jest on wymieniony w dziesiątkach innych klas, które są częścią wiązania XML. Gdybym mógł przesłonić wartość, nie musiałbym w ogóle zmieniać moich powiązań, domyślnie użyłaby mojej metody. Ale gdybym był zmuszony do stworzenia nowej metody, musiałbym zaktualizować te dziesiątki wiązań. Właśnie to musiałem zrobić. – scphantm

8

Użyj Apache Commons Lang:

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

cytat z Javadoc for EnumUtils.getEnum:

Pobiera enum dla klasy, wracając null, jeśli nie została znaleziona.

Metoda ta różni się od Enum.valueOf (java.lang.Class, java.labg.String) tym, że nie zgłasza wyjątek dla nieprawidłowej nazwy wyliczeniowego.

+0

Dobra odpowiedź. Szkoda, że ​​potrzebujemy dodatkowych bibliotek, aby zachowywać się w Javie tak, jak chcielibyśmy ... – Betlista

2

Nie trzeba przesłonić valueOf. Oto, co zrobiłem:

Musiałem "parsować" niektóre napisy do wyliczeń i nie pasowały one do ich nazw deklaracji, więc wykonałem rodzaj reimplementacji 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; 
     } 
    } 

Ten kod jest przetestowany i działa.

można używać jak:

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

I to wyjście będzie:

FIN #FIN# 
PUT PUT 

Nadzieję, że to pomaga.

Powiązane problemy