为什么使用Collection <String> .class非法?

Pet*_*ens 36 java

我对仿制药感到困惑.您可以声明一个字段,如:

Class<Collection<String>> clazz = ...
Run Code Online (Sandbox Code Playgroud)

您可以使用以下命令分配此字段似乎合乎逻辑:

Class<Collection<String>> clazz = Collection<String>.class;
Run Code Online (Sandbox Code Playgroud)

但是,这会产生错误:

令牌">"上的语法错误,此令牌后预期为void

所以看起来.class运算符不适用于泛型.所以我尝试过:

  class A<S> { }
  class B extends A<String> { }
  Class<A<String>> c = B.class;
Run Code Online (Sandbox Code Playgroud)

也不起作用,生成:

类型不匹配:无法转换 Class<Test.StringCollection> to Class<Collection<String>>

现在,我真的不明白为什么这不起作用.我知道泛型类型没有具体化,但在这两种情况下,它似乎完全是类型安全的,无需访问运行时泛型类型.有人有想法吗?

pol*_*nts 31

泛型是不变的.

Object o = "someString"; // FINE!
Class<Object> klazz = String.class; // DOESN'T COMPILE!
// cannot convert from Class<String> to Class<Object>
Run Code Online (Sandbox Code Playgroud)

根据您需要的内容,您可以使用通配符.

Class<? extends Number> klazz = Integer.class; // FINE!
Run Code Online (Sandbox Code Playgroud)

或许你需要这样的东西:

Class<List<String>> klazz =
   (Class<List<String>>) new ArrayList<String>().getClass();
// WARNING! Type safety: Unchecked cast from
//   Class<capture#1-of ? extends ArrayList> to Class<List<String>>
Run Code Online (Sandbox Code Playgroud)

对于非运行时的情况,你似乎有一个很好的把握,但无论如何,这是一个引用,从泛型Java教程,精细打印:一个通用类是由它的所有调用共享:

以下代码片段打印什么?

List <String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());
Run Code Online (Sandbox Code Playgroud)

你可能会想说false,但你错了.它打印true,因为泛型类的所有实例都具有相同的运行时类,而不管它们的实际类型参数如何.

也就是说,有没有这样的东西List<String>.classList<Integer>.class; 只有List.class.

这也反映在JLS 15.8.2类文字中

类文字是一个表达式,由类,接口,数组或基本类型的名称,或伪类型void,后跟a .和令牌组成class.

请注意省略泛型类型参数/参数的任何限制.此外,

如果发生以下任何情况,则为编译时错误:

  • 命名类型是类型变量或参数化类型,或者是元素类型是类型变量或参数化类型的数组.

也就是说,这也不会编译:

void <T> test() {
    Class<?> klazz = T.class; // DOESN'T COMPILE!
    // Illegal class literal for the type parameter T
}
Run Code Online (Sandbox Code Playgroud)

基本上你不能将泛型与类文字一起使用,因为它没有意义:它们是不具体的.

  • @Peter:你说"实际上,不变性就是伎俩" - 更确切地说,使用(有界)通配符是"技巧".您应该阅读更多关于它们如何使用,PECS(生产者扩展消费者超级)原则及其促进的原因等. (2认同)