2017-04-11 7137 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")); 
}