theintz
theintz

Reputation: 1987

Generic Enums in Java

I have a basic Configuration class that provides all its possible keys and the type of the corresponding value types in an enum like so:

public class Configuration {
    public static enum Key {
        FIRST_KEY("actual key 1", Long.class),
        ANOTHER_KEY("actual key 2", Integer.class)

        public final String value;
        public final Class type;

        Key(String value, Class type) {
            this.value = value;
            this.type = type;
        }
    }
}

What I would like to do is write a method that parses the value of a given key from a String and returns the value as the appropriate type. Basically this:

public <T> T getValue(Key<T> key, String valueStr);

This attempt fails at the method declaration already, since its appears that Enums in Java can not have type arguments. Any ideas on how to achieve something similar to this?

Upvotes: 5

Views: 1296

Answers (5)

drobson
drobson

Reputation: 955

Have a getType method in your Enum, then use that to help cast your string.

getType() in the Enum.

 public Class getType()
 {      
    return type;    
 } 

Using the getType() method to help cast the string.

 public Object getValue(Key key , String strValue)
 {
    return key.getType().cast(strValue) ;   
 }

You might have to write an IF statement to work out how to parse the String for different objects e.g. for Integer use the Integer.parseInt(s) method, otherwise you'll get a ClassCastExcpetion

Upvotes: -1

irreputable
irreputable

Reputation: 45443

You could simply

public <T> T getValue(Key key, String valueStr);

It lacks compile time checking though, so this will pass compile

Short value = getValue(FIRST_KEY, string);  // should be Long

The better answer? Don't use enum! Make Key<T> an ordinary class.

public static class Key<T>
{
    public static final Key<Long> FIRST_KEY 
                  = new Key("actual key 1", Long.class);
    ...

    public final String value;
    public final Class<T> type;

    Key(String value, Class<T> type) {
        this.value = value;
        this.type = type;
    }
}

Upvotes: 3

cl-r
cl-r

Reputation: 1264

You can initialyze a Map<Class, String>, and add a method for this.

EDIT after comments

Map<Class, Enum>, give FIRST_KEY for a get(objectParameter.getClass()), if objectParameter is a Long

Naturally, if Long have more than one key : Map<Class, Set< Enum>> and choose in the result from the environment you are working.

Upvotes: 0

David Grant
David Grant

Reputation: 14223

I'd provide a type hint in the getValue() method, e.g.

public <T> T getValue(Key k, Class<T> type);

You can check if the type is correct inside the method by checking the key.

Upvotes: 2

Istvan Neuwirth
Istvan Neuwirth

Reputation: 398

You have to pass the class of enum as parameter:

public <T extends Enum> T getValue(key, Class<T extends Enum> enumClazz) {
    return enumClazz.cast(...);
}

Upvotes: -1

Related Questions