2017-04-11 7134 views
1

我知道我可以使用下面的僞代碼(我知道Enum沒有contains方法,這僅僅適用於我的示例)檢查特定枚舉中是否包含字符串。 :在Java中傳遞枚舉類型值作爲參數

Enum Animal { 
    Dog, 
    Cat, 
    Human 
} 

public boolean CheckAnimalValid(String name){ 
    return Animal.contains(name)? true : false; 
} 

但在以前的方式,我需要實現CheckValid方法每個枚舉類,因爲我需要知道WHICH Enum類,我應該去檢查。

我想知道有沒有什麼方法傳遞枚舉類型作爲參數傳遞給函數,這樣我可以這樣做:

Enum Animal { 
     Dog, 
     Cat, 
     Person 
    } 

Enum Plant { 
    Grass, 
    Flower, 
    Tree 
} 

public boolean CheckEnumValid(String name, what_should_I_do? enum){ 
    return enum.contains(name)? true : false; 
} 

我想知道哪種類型(或關鍵字)我應該使用what_should_I_do?在前面的代碼中。我知道我應該使用泛型,但我不知道該怎麼做。謝謝!

+1

我根本不寫。我會直接使用'Enum.valueOf(類 enumType,String name)'。 NB在Enum中沒有'contains()'方法,除非你自己把它放在那裏。 – EJP

+0

@EJP感謝您的建議。你是對的,'valueOf()'可以實現我所需要的幾乎;但我仍然想知道如何實現使用泛型。我試過'公開>',它可以被編譯,但是我不知道如何調用這個函數。我不能使用'CheckValid(「test」,Plant);''或者'CheckValid(「test」,Plant.class);'。 – Alanight

+0

'Enum.valueOf(類枚舉類型,字符串名稱)'*已經*用泛型實現它。你不需要別的東西。 – EJP

回答

5

如果名稱與該類型的枚舉常量匹配,則可以使用靜態方法Enum.valueOf(Class<T> enumType, String name),該方法返回類型爲T的枚舉。否則會拋出IllegalArgumentException

用法示例:

Enum.valueOf(Plant.class, "Flower"); 

在返回布爾值的方法裹:

public <T extends Enum<T>> boolean checkValid(Class<T> enumType, String name){ 
    try { 
     Enum.valueOf(enumType, name); 
     return true; 
    } catch(IllegalArgumentException e) { 
     return false; 
    } 
} 
+0

'Plant.class'應該是'enumType',並且'enumType'實際上應該是'Class >',以獲得更多的類型安全性。 – EJP

+0

@EJP你說得對,謝謝! – Kapep

+0

@Kapep謝謝!我試過你的方法,而這正是我需要的! – Alanight

0

如果實現一個通用的方法,而不是這將是很好,Java允許使用contrains這樣你就可以肯定只能通過枚舉,並且要感謝接口,您可以在編譯時限制允許或不允許的枚舉:

定義這種通用方法

public <T extends Enum<?> & ITag> void printEnum(T d) { 
     System.out.println(d.name()); 
    } 

定義標記接口:

interface ITag { 
} 

現在你可以標籤的枚舉,只有在方法有效:

enum Color implements ITag { 
    RED, GREEN, BLUE 
} 

enum STATE { 
    ON, OFF 
} 

enum CONNECTION { 
    UDP, TCP 
} 

的結果,你可以檢查的方法是在編譯時採用正確的參數...

printEnum(Color.GREEN); //valid 
printEnum(STATE.OFF);// invalid The method printEnum(T)... is not applicable for the arguments.. 
printEnum(CONNECTION.UDP);// invalid The method printEnum(T)... is not applicable for the arguments.. 
printEnum("Green"); // invalid The method printEnum(T)... is not applicable for the arguments.. 
0

不確定,如果我完全理解你的需要,但我懷疑你想在查找任何enumString - 如果是這種情況,那麼有幾種方法可以做到這一點。

首先 - 讓我們定義你在找什麼 - 像這樣?

interface Lookup<S,T> { 
    T lookup(S s); 
} 

現在你可以調整每enum做這樣的事情:

enum Animal implements Lookup<String,Animal>{ 
    Dog, 
    Cat, 
    Person; 
    Map<String,Animal> lookup = Arrays.stream(Animal.values()) 
      .collect(Collectors.toMap(e -> e.name(), e -> e)); 
    public Animal lookup(String name) { 
     return lookup.get(name); 
    } 
} 

但我懷疑你想這樣做沒有黑客所有enums - 這將是一個痛苦。這裏有一個使用助手對象的方法。現在

class EnumLookup<E extends Enum<E>> implements Lookup<String,E> { 
    final Map<String,E> lookup; 

    public EnumLookup(Class<E> clazz) { 
     lookup = Arrays.stream(clazz.getEnumConstants()) 
       .collect(Collectors.toMap(e -> e.name(), e -> e)); 
    } 

    @Override 
    public E lookup(String s) { 
     return lookup.get(s); 
    } 
} 

您可以創建其中的一個來詢問enum只要你喜歡。

enum Plant { 
    Grass, 
    Flower, 
    Tree; 
} 

public void test() { 
    EnumLookup<Plant> lookup = new EnumLookup<>(Plant.class); 
    System.out.println("Tree -> "+lookup.lookup("Tree")); 
}