开发者

Calling a method with an arg of Class<T> where T is a parameterized type

开发者 https://www.devze.com 2022-12-22 19:52 出处:网络
I\'m attempting to call a constructor method that looks like: public static SomeWrapper<T> method(Class<T> arg);

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 literal String.class denotes the Class object that represents the type String and is identical to the Class object that is returned when method getClass is invoked on a String 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 and List<?>.class, since no such Class objects exist. Only the raw type List has a Class object that represents its runtime type. It is referred to as List.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);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号