0

Possible Duplicate:
get type of a generic parameter in java with reflection
Get generic type of class at runtime

Suppose I have a class like this:

public class Foo<T, M> {
  Pair<T, M> bar;
}

Is there a way to determine what "T" and "M" is at runtime? e.g.

Foo<String, Integer> foo1 = new Foo<String, Integer>();
Foo<Integer, Boolean> foo2 = new Foo<Integer, Boolean>();
// what happens next?

Thanks!

Community
  • 1
  • 1
Peter
  • 797
  • 3
  • 12
  • 18

3 Answers3

4

No. There isn't. That's pretty much the definition of type erasure.

That said, there are some funky workarounds. You could explicitly look up the components of the pair, and ask their types. You could use the cool trick with anonymous inner classes that e.g. Guava's TypeToken uses -- you can't determine the type of new Foo<String, Integer>() at runtime, but you can determine the type of new Foo<String, Integer>() {} at runtime -- note the anonymous inner class, which does retain the generic parameters specified for its superclass, namely Foo. (Disclosure: I contribute to Guava.)

Frequently, the best solution of all is to avoid needing this information in the first place. There isn't a general cookbook for how to do this, but it's usually possible.

All that said, the only general-case solution to this need is to pass around the Class metadata explicitly.

Louis Wasserman
  • 172,699
  • 23
  • 307
  • 375
  • "but you can determine the type of" well, no, you are determining the type of its superclass. "note the anonymous inner class, which does retain the generic parameters specified for its superclass" All classes retain the generic parameters for their superclass – newacct Jul 19 '12 at 19:10
  • ...That's the point. You're exploiting that fact. – Louis Wasserman Jul 19 '12 at 19:42
1

Runtime generic information will be erased. As soon as your class compiled, all generic type information will be erased and replaced:

All type parameters in generic types with their bounds or Object if the type parameters are unbounded

kosa
  • 63,683
  • 12
  • 118
  • 157
0

Actually, the java.lang.reflect.Field preserves the generic information; therefore, via reflection you can get generic information but only for class/instance variables (not method return types, and not local variables).

So in your case, if foo1 and foo2 were instance variables in some class:

class FooTest {
    Foo<String, Boolean> foo1;
}

then FooTest.class.getDeclaredField("foo1").getGenericType() will return a ParameterizedType instance where you can check the getActualTypeArguments().

Costi Ciudatu
  • 33,403
  • 5
  • 52
  • 89