There are no class literals for concrete parameterized types or wildcard parameterized types. From Angelika Langer's generics tutorial:
Wildcard parameterized types lose their type arguments when they are translated to byte code 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 to forming class literals such as
List<?>.class
,List<? extends Number>.class
andList<Long>.class
, since no suchClass
objects exist. Only the raw typeList
has aClass
object that represents its runtime type. It is referred to asList.class
.
There are no class literals for concrete parameterized types for the same reasons, which in a nutshell are type erasure.
For your purposes, you will just need to do an unchecked cast of the class literal:
Class<Map<String, ?>> c = (Class<Map<String, ?>>)(Class<?>)Map.class;
Note that the double cast through Class<?>
is necessary because a direct conversion from Class<Map>
to Class<Map<String, ?>>
is illegal.