2011-10-05 11 views
11

Necesito volver a implementar el método enum.valueof de algunas de mis enumeraciones para que ya no arrojen excepciones, en su lugar, simplemente devuelven null si no existe un valor en la enumeración.Cómo reimplementar valueof en la enumeración

Estoy intentando el básico

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

pero no está funcionando, diciendo que necesito para anular o aplicar un tipo súper.

Creo que se me ocurre una súper clase, pero no estoy seguro de cómo armar esto. ¿Algunas ideas?

Respuesta

17

No puede. Tendrás que definir otro método diferente. El método valueOf es generado automáticamente por el compilador.

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

Sí, supongo que tendré que hacerlo de esta manera. solo esperaba no tener que cambiar tanto. gracias – scphantm

+0

Sí, no estoy seguro de por qué Java no permite esto ... la invalidación de 'valueOf' tendría mucho más sentido que la implementación de la suya y que los clientes de su enum necesitan aprender su convención .. –

+0

No estoy seguro, pero creo que la implementación de su método realmente requiere que la enumeración tenga un método 'getName()' adicional. Creo que realmente debería usar el 'nombre()' incorporado para obtener el nombre real de la enumeración. – schneida

0

Puede considerar crear un nuevo método estático (diferente nombre como convertir) en sus clases enum.

public enum MyEnum{ 
     .... 

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

¿Es absolutamente necesario que el método se llama valueOf como el método que tienen las enumeraciones de forma automática? En el proyecto en el que estoy trabajando tenemos métodos similares, pero los llamamos de manera diferente; por ejemplo, forName:

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

    return null; 
} 
+1

Quería llamarlo valueOf porque está referenciado en docenas de otras clases que son parte del enlace XML. Si pudiera anular el valor de, entonces no tenía que cambiar mis enlaces, usarían mi método por defecto. Pero, si tuviera que crear un nuevo método, tendría que actualizar esas docenas de enlaces. Que es lo que terminé teniendo que hacer. – scphantm

8

Uso de Apache Commons Lang:

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

Presupuesto de la Javadoc for EnumUtils.getEnum:

Obtiene la enumeración de la clase, devolviendo un valor nulo si no se encuentra.

Este método difiere de Enum.valueOf (java.lang.Class, java.lang.String), ya que no produce una excepción para un nombre de enumeración no válido.

+0

Buena respuesta. Eso es malo, necesitamos bibliotecas adicionales para comportar Java como nos gustaría ... – Betlista

2

No tiene que sobrescribir valueOf. Esto es lo que hice:

Tuve que "analizar" algunas cadenas en las enumeraciones y no coincidían con sus nombres de declaración, así que hice una especie de reimplementación de 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; 
     } 
    } 

Este código ha sido probado y funciona.

Se puede utilizar como:

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

Y es la salida sería:

FIN #FIN# 
PUT PUT 

espero que ayude.

Cuestiones relacionadas