Java: instantiating an enum using reflection

前端 未结 5 1460
甜味超标
甜味超标 2020-12-08 09:07

Suppose you have a text file like:

my_setting = ON
some_method = METHOD_A
verbosity = DEBUG
...

That you wish to to update a corresponding

相关标签:
5条回答
  • 2020-12-08 09:51
    field.set(this, Enum.valueOf((Class<Enum>) field.getType(), value));
    
    • getClass() after getType() should not be called - it returns the class of a Class instance
    • You can cast Class<Enum>, to avoid generic problems, because you already know that the Class is an enum
    0 讨论(0)
  • 2020-12-08 09:55

    You have an extra getClass call, and you have to cast (more specific cast per Bozho):

    field.set(test, Enum.valueOf((Class<Enum>) field.getType(), value));
    
    0 讨论(0)
  • 2020-12-08 09:56

    You may code your Enum similar tho this:

    public enum Setting {
    
        ON("ON"),OFF("OFF");
    
        private final String setting;
    
        private static final Map<String, Setting> stringToEnum = new ConcurrentHashMap<String, Setting>();
        static {
            for (Setting set: values()){
                stringToEnum.put(set.setting, set);
            }
        }
    
        private Setting(String setting) {
            this.setting = setting;
        }
    
        public String toString(){
            return this.setting;
        }
    
        public static RequestStatus fromString(String setting){
            return stringToEnum.get(setting);
        }   
    }
    

    Then you may easily create Enum from String without reflection:

    Setting my_settings = Setting.fromString("ON");
    

    This solution is not originated from myself. I read it from somewhere else, but I can't recall the source.

    0 讨论(0)
  • 2020-12-08 10:05

    The accepted answer results in warnings because it uses the raw type Enum instead of Enum<T extends Enum<T>>.

    To get around this you need to use a generic method like this:

    @SuppressWarnings("unchecked")
    private <T extends Enum<T>> T createEnumInstance(String name, Type type) {
      return Enum.valueOf((Class<T>) type, name);
    }
    

    Call it like this:

    Enum<?> enum = createEnumInstance(name, field.getType());
    field.set(this, enum);
    
    0 讨论(0)
  • 2020-12-08 10:09

    Alternative solution with no casting

    try {
        Method valueOf = field.getType().getMethod("valueOf", String.class);
        Object value = valueOf.invoke(null, param);
        field.set(test, value);
    } catch ( ReflectiveOperationException e) {
        // handle error here
    }
    
    0 讨论(0)
提交回复
热议问题