在Java中将枚举类型值作为参数传递

在Java中将枚举类型值作为参数传递,java,enums,Java,Enums,我知道我可以使用下面伪代码描述的概念来检查特定枚举中是否包含字符串(我知道对于Enum,没有contains方法,这只是我的示例): 但是在前面的方法中,我需要为每个Enum类实现CheckValid方法,因为我需要知道我应该检查哪个Enum类 我想知道是否有任何方法可以将枚举类型作为参数传递给函数,以便我可以这样做: Enum Animal { Dog, Cat, Person } Enum Plant { Grass,

我知道我可以使用下面伪代码描述的概念来检查特定枚举中是否包含字符串(我知道对于
Enum
,没有
contains
方法,这只是我的示例):

但是在前面的方法中,我需要为每个Enum类实现CheckValid方法,因为我需要知道我应该检查哪个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;
}

我想知道在前面的代码中,我应该在应该做什么?中使用哪种类型(或关键字)。我知道我应该使用泛型,但我不知道怎么做。谢谢

如果名称与该类型的枚举常量匹配,则可以使用静态方法返回类型为
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;
    }
}
public boolean checkValid(类枚举类型,字符串名称){
试一试{
Enum.valueOf(enumType,name);
返回true;
}捕获(IllegalArgumentException e){
返回false;
}
}

如果您实现一个通用方法就好了,java允许使用contrains,因此您可以确保只传递一个枚举,多亏了接口,您可以在编译时限制允许或不允许哪些枚举:

定义此通用方法

public <T extends Enum<?> & ITag> void printEnum(T d) {
        System.out.println(d.name());
    }
现在,您可以标记仅在方法中有效的枚举:

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..

不确定我是否完全理解您的需要,但我怀疑您希望通过
字符串
查找任何
枚举
-如果是这样,那么有几种方法可以做到这一点

首先,让我们定义一下你在寻找什么——像这样的东西

interface Lookup<S,T> {
    T lookup(S s);
}
但我怀疑您希望在不黑客您的
枚举的所有的情况下执行此操作,这将是一种痛苦。这里有一个使用辅助对象的方法

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.valueOf(类enumType,字符串名)
。注意在
枚举中没有
contains()
方法,除非您自己把它放在那里。@EJP谢谢您的建议。你说得对,
valueOf()
几乎可以满足我的需要;但我仍然想知道如何使用泛型实现这一点。我尝试了
public
,它可以被编译,但是我不知道如何调用该函数。我不能使用
CheckValid(“测试”,工厂)或<代码>检查有效(“测试”,工厂等级)
Enum.valueOf(类enumType,字符串名)
已经通过泛型实现了它。您不需要其他任何东西。@EJP我知道在
Enum
中没有
contains()
方法,这只是我的示例。我在上一篇评论中提到的问题是,我不知道如何调用该函数。请参阅@Kapep的答案。我最初的“现在已删除”注释不正确。
Plant.class
应该是
enumType
,而
enumType
应该是
class
,以确保更多的类型安全。@Kapep谢谢!我试过你的方法,这正是我需要的!
interface Lookup<S,T> {
    T lookup(S s);
}
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);
    }
}
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 Plant {
    Grass,
    Flower,
    Tree;
}

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