使用类<T>的arg调用方法,其中T是参数化类型

Bri*_*ris 4 java generics

我试图调用一个看起来像这样的构造函数方法:

public static SomeWrapper<T> method(Class<T> arg);
Run Code Online (Sandbox Code Playgroud)

当T是像String或Integer这样的非参数化类型时,调用很简单:

SomeWrapper<String> wrapper = method(String.class);
Run Code Online (Sandbox Code Playgroud)

当T是参数化类型时,事情变得棘手List<String>.以下内容无效:

SomeWrapper<List<String>> wrapper = method(List<String>.class);
Run Code Online (Sandbox Code Playgroud)

关于我唯一能想到的是:

List<String> o = new ArrayList<String>();
Class<List<String>> c = (Class<List<String>>) o.getClass();
SomeWrapper<List<String>> wrapper = method(c);
Run Code Online (Sandbox Code Playgroud)

当然有一种更简单的方法,不需要构建额外的对象?

cle*_*tus 6

不,没有.没有ClassList<String>,只List.

请参阅为什么没有具体参数化类型的类文字?:

因为参数化类型没有确切的运行时类型表示.

类文字表示Class 表示给定类型的对象.例如,类literal String.class表示Class 表示类型的对象, String并且与在 Class对象上getClass调用方法时返回的 String对象相同.类文字可用于运行时类型检查和反射.

参数化类型在编译期间在称为类型擦除的过程中转换为字节代码时会丢失其类型参数.作为类型擦除的副作用,泛型类型的所有实例化共享相同的运行时表示,即相应原始类型的表示.换句话说,参数化类型没有自己的类型表示.因此,存在在形成文字类诸如没有意义的List<String>.class, List<Long>.class并且List<?>.class,由于没有这样的Class对象是否存在.只有raw类型List有一个Class 表示其运行时类型的对象.它被称为 List.class.

我个人会这样做:

public static <C extends Collection<T>,T> SomeWrapper<C> method(
  Class<C> collClass, Class<T> itemClass)
Run Code Online (Sandbox Code Playgroud)