简体   繁体   中英

Pass Enum type value as a parameter in Java

I know I can check whether a String is contained in a specific Enum using the concept described by pseudo code below(I know there's no contains method for Enum , that's just for my example) :

Enum Animal {
    Dog,
    Cat,
    Human
}

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

But in previous way I need to implement the CheckValid method for each Enum class, since I need to know WHICH Enum class should I to check.

I want to know is there any method to pass Enum type as a parameter to a function, so that I can do in this way:

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;
}

I want to know which type(or keyword) should I use in what_should_I_do? in the previous code. I know I should use Generics, but I don't know how to do. Thanks!

You can use the static method Enum.valueOf(Class<T> enumType, String name) which returns an enum of type T , if the name matches an enum constants of that type. Otherwise is throws an IllegalArgumentException .

Example usage:

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

Wrapped in a method that returns a boolean:

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

Not certain if I fully understand your need but I suspect you want to lookuup in any enum by String - if that is the case then there are several ways to do this.

First - let's define what you are looking for - something like this?

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

Now you could adjust every enum to do something like this:

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);
    }
}

But I suspect you want to do this without hacking all of your enums - which would be a pain. Here's one method using a helper object.

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);
    }
}

Now you can create one of these to interrogate the enum whenever you like.

enum Plant {
    Grass,
    Flower,
    Tree;
}

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

It would be nice if you implement a generic method instead, java allows using contrains so you can for sure PASS ONLY AN ENUM, and thanks to interfaces you can restrict at compiling time what enums are allowed or not:

Define this generic method

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

define a tag interface:

interface ITag {
}

now you can Tag the enums that only valid in the method:

enum Color implements ITag {
    RED, GREEN, BLUE
}

enum STATE {
    ON, OFF
}

enum CONNECTION {
    UDP, TCP
}

as result, you can check if a method is taking the correct param at compiling time...

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM