Java-如何通过字符串访问Enum Class和Enum对象?

时间:2019-02-14 05:00:48

标签: java enums

所以我有一个带有多个枚举的Java类

public class Enumerations {
    public enum Days {
        Monday("MON")
        Tuesday("Tue")

        string value;
        private Days(String value){
            this.value = value
        }
        public string getValue(){
            return this.value;
        }
    }
    public enum Months{
        January("JAN")
        APRIL("APR")

        string value;
        private Months(String value){
            this.value = value
        }
        public string getValue(){
            return this.value;
        }
    }
}

现在我有另一个类,我想通过字符串访问枚举类,因为我无法直接实例化枚举,因为我不知道要使用的枚举,而是从可变字符串访问枚举值(不知道也是如此)。

class EnumParser{
    public static void main(String args[]){
        String enum = "Days";     //Will get this value from external source so its variable(Can be months or days)
        String value = "Monday"   //This is going to variable as well with value unknown.
    }
}

那么我如何在这里使用字符串变量将输出作为“ MON”

Enumerations.{{Days}}.{{Monday}}.getValue();

编辑了该问题以得到更清晰的视图,“ Days”和“ Mondays”都是变量。

3 个答案:

答案 0 :(得分:1)

您可以使用if-elseswitch语句来确定要使用的枚举,然后使用valueOf()

String e = "Days";
String value = "Monday";

if (e.equalsIgnoreCase(Enumerations.Days.class.getSimpleName())) {
    System.out.println(Enumerations.Days.valueOf(value).getValue());
} else if (e.equalsIgnoreCase(Enumerations.Months.class.getSimpleName())) {
    System.out.println(Enumerations.Months.valueOf(value).getValue());
} else {
    System.out.println("Could not find enum");
}

输出:

MON

更新是基于您可能有200多个枚举的注释:

您可以像这样使用反射:

String e = "Days";
String value = "Monday";

String res = Arrays.stream(Enumerations.class.getDeclaredClasses())
        .filter(c -> c.getSimpleName().equalsIgnoreCase(e))
        .findFirst()
        .map(c -> {
            String result = null;
            try {
                Object o = c.getMethod("valueOf", String.class).invoke(null, value);
                result = (String) o.getClass().getMethod("getValue").invoke(o);
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e1) {
                e1.printStackTrace();
            }
            return result;
        }).orElse("Could not find");
System.out.println(res); //prints MON

答案 1 :(得分:0)

使用静态方法为您检索适当的枚举值:

//inside Days, skips some excess array creation
private static final Days[] VALUES = Days.values();

public static Days getDay(String day) {
    return Arrays.stream(VALUES)
        .filter(d -> d.value.equalsIgnoreCase(day))
        .findAny(); //Optional<Days>
        //can use #orElse/#orElseThrow to decide behavior for a mismatch
}

然后只需直接获取枚举即可:

Days monday = Days.getDay("MON");

您可以根据需要创建多种方法来过滤这些输入。更进一步,如果您真的想发疯,可以通过Predicate<Days>(或任何枚举)并以这种方式进行过滤:

public static Days getDay(Predicate<Days> filter) {
    return Arrays.stream(VALUES)
        .filter(filter)
        //In this case I'm returning null for no match
        .findAny().orElse(null);
}

然后:

Days monday = Days.getDay(d -> d.getValue().equalsIgnoreCase("MON"));

现在在严格的Monday情况下,您可以使用Days#valueOf,但是如果搜索的字符串没有枚举常量,这将引发错误。

Days monday = Days.valueOf("Monday"); //okay
//all of these below would throw an error
monday = Days.valueOf("monday");
monday = Days.valueOf("MONDAY");
monday = Days.valueOf("not even close to monday");

我还将遵守此处的枚举约定(所有大写字母和下划线代表空格,因此MONDAY)。

最后,如果这不仅是一个示例问题,而且您实际上正在使用天/日历变量等,则默认jdk中已经有DayOfWeekMonth枚举。 / p>

答案 2 :(得分:0)

尝试反射方式;

package com.company;

import java.lang.reflect.Method;

class Enumerations {
    public enum Days {
        Monday("MON"),
        Tuesday("Tue");

        String value;
        Days(String value){
            this.value = value;
        }
        public String getValue(){
            return this.value;
        }
    }
    public enum Months{
        January("JAN"),
        APRIL("APR");

        String value;
        Months(String value){
            this.value = value;
        }
        public String getValue(){
            return this.value;
        }
        }
}
public class Main {

    public static void main(String[] args) throws Exception {
        // know the specific class name
        System.out.println(Enumerations.Months.class);
        String enumName = "Days";
        String value = "Monday";
        // get the class by class name
        Class c = Class.forName("com.company.Enumerations$" + enumName);
        // new the object by value
        Object o = Enum.valueOf(c, value);
        // get the method by name
        Method method = c.getMethod("getValue");
        // invoke the method
        System.out.println(method.invoke(o));
    }
}