Typically, I\'ve seen people use the class literal like this:
Class cls = Foo.class;
But what if the type is generic, e.g. List?
You can't due to type erasure.
Java generics are little more than syntactic sugar for Object casts. To demonstrate:
List list1 = new ArrayList();
List list2 = (List)list1;
list2.add("foo"); // perfectly legal
The only instance where generic type information is retained at runtime is with Field.getGenericType() if interrogating a class's members via reflection.
All of this is why Object.getClass() has this signature:
public final native Class> getClass();
The important part being Class>
.
To put it another way, from the Java Generics FAQ:
Why is there no class literal for concrete parameterized types?
Because parameterized type has no exact runtime type representation.
A class literal denotes a
Class
object that represents a given type. For instance, the class literalString.class
denotes theClass
object that represents the typeString
and is identical to theClass
object that is returned when methodgetClass
is invoked on aString
object. A class literal can be used for runtime type checks and for reflection.Parameterized types lose their type arguments when they are translated to byte code during compilation in a process called type erasure . As a side effect of type erasure, all instantiations of a generic type share the same runtime representation, namely that of the corresponding raw type . In other words, parameterized types do not have type representation of their own. Consequently, there is no point in forming class literals such as
List
,.class List
and.class List>.class
, since no suchClass
objects exist. Only the raw typeList
has aClass
object that represents its runtime type. It is referred to asList.class
.