A method call with an argument of class <T>, where T is a parameterized type
I am trying to call a constructor method that looks like this:
public static SomeWrapper<T> method(Class<T> arg); If T is a non-parameterized type of type String or Integer, the call is made directly:
SomeWrapper<String> wrapper = method(String.class); Everything becomes complicated if T is a parameterized type of type List<String> . The following is not valid:
SomeWrapper<List<String>> wrapper = method(List<String>.class); The only thing I could think of was:
List<String> o = new ArrayList<String>(); Class<List<String>> c = (Class<List<String>>) o.getClass(); SomeWrapper<List<String>> wrapper = method(c); Surely there is an easier way that does not require the construction of an additional object?
The following syntax was suggested on the Mockito discussion board :
SomeWrapper<List<Foo>> wrapper = (SomeWrapper<List<Foo>>) (Object) method(List.class); No no. For List<String> there is no Class , only List .
See Why is there no class literal for specific parameterized types? :
Because the parameterized type does not have an exact representation of the runtime type.
A class literal denotes a
Classobject that represents a given type. For example, the literal classString.classdenotes aClassobject that represents aStringtype and is identical to theClassobject that is returned when thegetClassmethod is called on aStringobject. A class literal can be used to check the type of runtime and to reflect.Parameterized types lose their type arguments when they are translated into byte code during compilation into a process called type erasure. As a side effect of type erasure, all instances of a common type share are the same representation of the run time, namely the corresponding raw type. In other words, parameterized types do not have a type representation. Therefore, there is no point in generating class literature such as
List<String>.class,List<Long>.classandList<?>.class, since suchClassobjects do not exist. Only the originalListtype has aClassobject representing its runtime type. It is calledList.class.
Personally, I would do this:
public static <C extends Collection<T>,T> SomeWrapper<C> method( Class<C> collClass, Class<T> itemClass)