Java - How to access Enum Class and Enum objects via strings?
所以我有一个具有多个Enums的Java类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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; } } } |
现在我有了另一个类,我想通过一个字符串访问枚举类,因为我不能直接实例化枚举,因为我不知道要使用的枚举,并且从变量字符串访问枚举值(也不知道这一点)。
1 2 3 4 5 6 |
号
那么,如何使用字符串变量得到输出为"mon"
1 | Enumerations.{{Days}}.{{Monday}}.getValue(); |
为了更清晰地理解问题,两天和星期一都是变量。
您可以使用
1 2 3 4 5 6 7 8 9 10 | 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"); } |
输出:
1 | MON |
号
根据可能有200多个枚举的注释进行更新:
您可以这样使用反射:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 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)); } } |
。
生成一个静态方法,该方法为您检索适当的枚举值:
1 2 3 4 5 6 7 8 9 | //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 } |
。
然后,只需直接获取枚举即可:
1 | Days monday = Days.getDay("MON"); |
如果您愿意,您可以使用多种方法来过滤这些输入。更进一步,如果你真的想发疯,你可以通过一个
1 2 3 4 5 6 | 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); } |
。
然后:
1 | Days monday = Days.getDay(d -> d.getValue().equalsIgnoreCase("MON")); |
。
现在,在严格使用
1 2 3 4 5 | 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"); |
我也会遵守这里的Enum惯例(所有大写字母和下划线都表示间距,所以
最后,如果这不仅仅是一个示例问题,而且您实际使用的是天/日历变量等,那么缺省JDK中已经有了