【问题标题】:Get value of enum by reflection通过反射获取枚举的值
【发布时间】:2014-06-17 09:19:49
【问题描述】:

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

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

  public static String key;

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

现在,我想通过反射获取此枚举的键(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);
}

输出是: 跑步 停止 空闲

但是,我想要字符串 SystemRunning、tmpIdle 等。

非常感谢您。

【问题讨论】:

  • 为什么是key static
  • stackoverflow.com/questions/5316311/… 做了这样的事情(不需要反思)。代码中的一个小错误:为字段 key 删除 static。知道Mode.values()

标签: java reflection enums


【解决方案1】:

首先,您需要将key 设为非静态变量。

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

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

public String getKey() {
    return key;
}

然后将您的 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
}

【讨论】:

    【解决方案2】:

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

    如果你知道你所有的枚举都有一个 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;
      }
    }
    

    通过反射获取'key':

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

    【讨论】:

    • 这应该是正确的答案,因为它没有引入额外的吸气剂
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2013-05-28
      • 2017-11-07
      • 2011-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多