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?

+4
source share
2 answers

The following syntax was suggested on the Mockito discussion board :

 SomeWrapper<List<Foo>> wrapper = (SomeWrapper<List<Foo>>) (Object) method(List.class); 
+3
source

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 Class object that represents a given type. For example, the literal class String.class denotes a Class object that represents a String type and is identical to the Class object that is returned when the getClass method is called on a String object. 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>.class and List<?>.class , since such Class objects do not exist. Only the original List type has a Class object representing its runtime type. It is called List.class .

Personally, I would do this:

 public static <C extends Collection<T>,T> SomeWrapper<C> method( Class<C> collClass, Class<T> itemClass) 
+6
source

Source: https://habr.com/ru/post/1303519/


All Articles