views:

72

answers:

4

Assume I have a generic type P which is an Enum, that is <P extends Enum<P>>, and I want to get the Enum value from a string, for example:

String foo = "foo";
P fooEnum = Enum.valueOf(P.class, foo);

This will get a compile error because P.class is invalid. So what can I do in order to make the above code work?

+3  A: 

There is no way in Java. Generic types are erased and converted to Object in byte code. The generic type ('P' in your case) is not a real class but just a placeholder.

Have a look at this question with great answers on type erasure.

Andreas_D
+1  A: 

Java implements generics using something called type erasure. What that means is the actual generic parameter is erased at runtime. Thus, you cannot infer type information from generic type parameters.

jjnguy
+4  A: 

You must have a runtime instance of this generic type somewhere so that you can just grab the declaring class by Enum#getDeclaringClass(). Assuming that you've declared P p somewhere as a method argument, here's an example.

E.g.

public static <P extends Enum<P>> P valueOf(P p, String name) {
    return Enum.valueOf(p.getDeclaringClass(), name);
}
BalusC
No there's no runtime instance p... If p exist, I don't need to run that line. I only have the enum name and want to get p from that string.
Samuel Yung
If there's no runtime instance, then you won't be able to reveal the generic type's runtime class. Generics in Java are not *reified* like in C#.
BalusC
A: 

You can get it at runtime by having the caller or some configuration provider it. For example, you could have Spring or whatever configure this.

class Converter<P extends Enum> {
    private Class<P> type;

    //setter and getter

    public P valueOf(String name) {
        return Enum.valueOf(type, name);
    }
}

And then configure it wherever it's needed.

sblundy