Is it possible to get the type of a generic parameter?
An example:
public final class Voodoo {
public static void chill(List<?> aListWithTypeSpiderMan) {
// Here I'd like to get the Class-Object 'SpiderMan'
Class typeOfTheList = ???;
}
public static void main(String... args) {
chill(new ArrayList<SpiderMan>());
}
}
I want to try to break down the answer from @DerMike to explain:
First, type erasure does not mean that the JDK eliminates type information at runtime. It's a method for allowing compile-time type checking and runtime type compatibility to coexist in the same language. As this block of code implies, the JDK retains the erased type information--it's just not associated with checked casts and stuff.
Second, this provides generic type information to a generic class exactly one level up the heirarchy from the concrete type being checked--i.e. an abstract parent class with generic type parameters can find the concrete types corresponding to its type parameters for a concrete implementation of itself that directly inherits from it. If this class were non-abstract and instantiated, or the concrete implementation were two levels down, this wouldn't work (although a little bit of jimmying could make it apply to any predetermined number of levels beyond one, or up to the lowest class with X generic type parameters, et cetera).
Anyway, on to the explanation. Here's the code again, separated into lines for ease of reference:
Let 'us' be the abstract class with generic types that contains this code. Reading this roughly inside out:
...and that's pretty much it. So we push type info from our own concrete implementation back into ourselves, and use it to access a class handle. we could double up getGenericSuperclass() and go two levels, or eliminate getGenericSuperclass() and get values for ourselves as a concrete type (caveat: I haven't tested these scenarios, they haven't come up for me yet).
It gets tricky if your concrete children are be an arbitrary number of hops away, or if you're concrete and not final, and especially tricky if you expect any of your (variably deep) children to have their own generics. But you can usually design around those considerations, so this gets you most of the way.
Hope this helped someone! I recognize this post is ancient. I'll probably snip this explanation and keep it for other questions.
Because of type erasure the only way to know the type of the list would be to pass in the type as a parameter to the method:
Use:
As pointed out by @bertolami, it's not possible to us a variable type and get its future value (the content of typeOfList variable).
Nevertheless, you can pass the class as parameter on it like this:
That's more or less what Google does when you have to pass a class variable to the constructor of ActivityInstrumentationTestCase2.
One construct, I once stumbled upon looked like
So there seems to be some reflection-magic around that I unfortunetly don't fully understand... Sorry.
Appendix to @DerMike's answer for getting the generic parameter of a parameterized interface (using #getGenericInterfaces() method inside a Java-8 default method to avoid duplication):