I'm attempting to call a constructor method that looks like:
public static SomeWrapper<T> method(Class<T> arg);
When T is an unparameterized type like String or Integer, calling is straightforward:
SomeWrapper<String> wrapper = method(String.class);
Things get tricky when T is a parameterized type like List<String>
. The following is not valid:
SomeWrapper<List<String>> wrapper = method(List<String>.class);
About the only thing I could come up with is:
List<String> o = new ArrayList<String>();
Class<List<String>> c = (Class<List<String>>) o.getClass();
SomeWrapper<List<String&开发者_开发问答gt;> wrapper = method(c);
Surely there is an easier way that doesn't require the construction of an additional object?
No there isn't. There is no Class
for List<String>
, only List
.
See 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<String>.class
,List<Long>.class
andList<?>.class
, since no suchClass
objects exist. Only the raw typeList
has aClass
object that represents its runtime type. It is referred to asList.class
.
Personally I would do this:
public static <C extends Collection<T>,T> SomeWrapper<C> method(
Class<C> collClass, Class<T> itemClass)
The following syntax was suggested on the Mockito issues discussion board:
SomeWrapper<List<Foo>> wrapper = (SomeWrapper<List<Foo>>) (Object) method(List.class);
精彩评论