我正在尝试调用构造函数方法,如下所示:
public static SomeWrapper<T> method(Class<T> arg);
当T是像String或Integer这样的非参数化类型时,调用很简单:
SomeWrapper<String> wrapper = method(String.class);
当T是像List<String>
这样的参数化类型时,事情变得棘手。以下内容无效:
SomeWrapper<List<String>> wrapper = method(List<String>.class);
关于我唯一能想到的是:
List<String> o = new ArrayList<String>();
Class<List<String>> c = (Class<List<String>>) o.getClass();
SomeWrapper<List<String>> wrapper = method(c);
当然有一种更简单的方法,不需要构建额外的对象?
答案 0 :(得分:6)
不,没有。 Class
没有List<String>
,只有List
。
请参阅Why is there no class literal for concrete parameterized types?:
因为参数化类型没有确切的运行时类型表示。
一个文字表示
Class
表示给定类型的对象。 例如,类文字String.class
表示Class
表示类型的对象String
与...相同 {。1}}时返回的对象 方法Class
在a上调用getClass
对象。一个类文字可以 用于运行时类型检查和 反思。参数化类型会丢失其类型 它们被翻译成时的参数 编译期间的字节代码 过程称为类型擦除。作为一个 所有类型擦除的副作用 泛型类型共享的实例化 相同的运行时表示, 即相应的原始 类型。换句话说,参数化 类型没有类型表示 他们自己的。因此,有 形成阶级文字没有意义 例如
String
,List<String>.class
和List<Long>.class
, 因为不存在这样的List<?>.class
个对象。 只有原始类型Class
才有List
表示其运行时的对象 类型。它被称为Class
。
我个人会这样做:
List.class
答案 1 :(得分:3)
Mockito issues discussion板上建议使用以下语法:
SomeWrapper<List<Foo>> wrapper = (SomeWrapper<List<Foo>>) (Object) method(List.class);