2011-10-05 448 views
11

我需要重新實現一些枚舉的enum.valueof方法,以便它們不再拋出異常,而只是在枚舉中不存在值時才返回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

是啊不知道爲什麼Java不允許這個..重寫'valueOf'會比實現你自己和讓你的枚舉的客戶需要學習你的約定更有意義.. –

+0

我不確定,但我認爲你的方法實現實際上需要enum有一個額外的'getName()'方法。我想你應該真的使用內建的name()來獲取枚舉的實際名稱。 – schneida

0

您可能會考慮在您的枚舉類中創建一個新的(不同的名稱,如convert)靜態方法。

public enum MyEnum{ 
     .... 

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

這種方法被稱爲valueOf是否像絕對需要自動枚舉的方法?在我目前正在研究的項目中,我們有類似的方法,但我們用不同的方式來稱呼它們;例如,forName

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

    return null; 
} 
+1

我想將它稱爲valueOf,因爲它在作爲XML綁定一部分的許多其他類中引用。如果我可以重寫valueof,那麼我根本不必更改綁定,他們會默認使用我的方法。但是,如果我被迫創建一個新的方法,我將不得不更新這些數十個綁定。這是我最終不得不做的。 – scphantm

8

使用Apache Commons Lang中:從Javadoc for EnumUtils.getEnum

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

報價:

獲取類枚舉,返回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 

希望它能幫助。