Java 通过反射获取枚举值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24260011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:10:17  来源:igfitidea点击:

Get value of enum by reflection

javareflectionenums

提问by blaster

I have an enum declared like this:

我有一个像这样声明的枚举:

public enum Mode{
  RUNNING("SytemRunning"),
  STOPPED("SystemStopped"),
  IDLE("tmpIdle");

  public static String key;

  private Mode(String key){
    this.key = key;
  }
}

Now, I want to get out the keys(SystemRunning, SystemStopped, tmpIdle) for this enum by reflection:

现在,我想通过反射获取此枚举的键(SystemRunning、SystemStopped、tmpIdle):

Class<?> c = Class.forName("Mode");
Object[] objects = c.getEnumConstants();
// now this is not what I want, but almost
for(Object obj : objects){
  System.out.println("value : " + obj);
}

the output is: RUNNING STOPPED IDLE

输出是:RUNNING STOPPED IDLE

However, I'd like to have the Strings SystemRunning, tmpIdle etc..

但是,我想要 Strings SystemRunning、tmpIdle 等。

Thank you very much in advance.

非常感谢您提前。

采纳答案by SudoRahul

Firstly, you need to make your keya non-static variable.

首先,您需要使您key的非静态变量。

private String key; // I made it private on purpose

Then you need to add a getter method in your enum which will return the key

然后你需要在你的枚举中添加一个 getter 方法,它将返回 key

public String getKey() {
    return key;
}

and then change your forloop to something like this.

然后将您的for循环更改为这样的内容。

for (Object obj : objects) {
    Class<?> clzz = obj.getClass();
    Method method = clzz.getDeclaredMethod("getKey");
    String val = (String) method.invoke(obj);
    System.out.println("value : " + val); // prints SytemRunning, SystemStopped and tmpIdle
}

回答by Cyrille Pontvieux

Add a method toString() that returns your key, then it will work. Your 'key' property shouldn't be static.

添加一个返回您的密钥的方法 toString() ,然后它将起作用。你的“key”属性不应该是静态的。

If you know that all your enums have a key property, you can ask for it directly by reflection too.

如果你知道你所有的枚举都有一个 key 属性,你也可以直接通过反射来请求它。

public enum Mode{
  RUNNING("SytemRunning"),
  STOPPED("SystemStopped"),
  IDLE("tmpIdle");

  public String key;

  private Mode(String key) {
    this.key = key;
  }
  public String toString() {
    return this.key;
  }
}

Get 'key' with reflection:

通过反射获取“密钥”:

Class<?> c = Class.forName("Mode");
Object[] objects = c.getEnumConstants();
// now this is not what I want, but almost
for(Object obj : objects) {
  try {
    Field keyField = obj.getClass.getDeclaredField("key");
    keyField.setAccessible(true); // if it is private for example.
    System.out.printn("value : " + keyField.get(obj);
  } catch (NoSuchFieldException e) {
    // fallback to toString()
    System.out.println("value : " + obj);
  }
}

回答by ChRoNoN

There is no point using reflection for this:

为此使用反射是没有意义的:

public interface EnumWithValue<T> {
    T getValue();
}

public enum Mode implements EnumWithValue<String> {
    RUNNING("SytemRunning"),
    STOPPED("SystemStopped"),
    IDLE("tmpIdle");

    private final String value;

    private Mode(String value) {
        this.value = value;
    }

    @Override
    public String getValue() {
        return value;
    }
}

public void test() {
    try {
        Class<? extends EnumWithValue<String>> clazz = (Class<? extends EnumWithValue<String>>) Class.forName("Mode");
        EnumWithValue<String>[] values = clazz.getEnumConstants();

        for (EnumWithValue<String> enumWithValue : values) {
            System.out.print(enumWithValue + " = " + enumWithValue.getValue());
        }
    } catch (ClassNotFoundException ex) {
        Logger.getLogger(ConverterEnum.class.getName()).log(Level.SEVERE, null, ex);
    }
}