views:

218

answers:

3

Hello,

Suppose you have a text file like:

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

That you wish to to update a corresponding object accordingly:

Setting my_setting = ON;
Method some_method = METHOD_A;
Verbosity verbosity = DEBUG;
...

Where all are different kind of enums.

I would like to have a generic way to instanciate the enum values. That is, at runtime using reflection, and without knowing the enum types of the object in advance.

I would have imagined something like this:

for (ConfigLine line : lines)
{
   String[] tokens = line.string.split("=", 2);
   String name = tokens[0].trim();
   String value = tokens[1].trim();

   try
   {
      Field field = this.getClass().getDeclaredField(name);   
      if(field.getType().isEnum())
      {
         // doesn't work (cannot convert String to enum)
         field.set(this, value);
         // invalid code (some strange generics issue)
         field.set(this, Enum.valueOf(field.getType().getClass(), value));
      }
      else
      { /*...*/ }
   }
   catch //...
}

The question is: what should there be instead? Is it even possible to instanciate an unknown enum given its String representation?

+1  A: 

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));
Matthew Flaschen
the generics problem still occurs
Bozho
+7  A: 
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
Bozho
Phunky! (8 more to go)
seanizer
A: 

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.

ThiamTeck
Not really helpful if you're using reflection, because you don't know if the enum in question is using this setup.
Kolky