为什么使用Collection< String> .class非法? [英] Why is using Collection<String>.class illegal?

查看:742
本文介绍了为什么使用Collection< String> .class非法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对仿制药感到困惑。您可以声明如下字段:

I am puzzled by generics. You can declare a field like:

Class<Collection<String>> clazz = ...

您可以将此字段指定为:

It seems logical that you could assign this field with:

Class<Collection<String>> clazz = Collection<String>.class;

然而,这会产生错误:


令牌>上的语法错误,此令牌后预期无效

Syntax error on token ">", void expected after this token

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

So it looks like the .class operator does not work with generics. So I tried:

  class A<S> { }
  class B extends A<String> { }
  Class<A<String>> c = B.class;

同样不起作用,生成:


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

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

Now, I really fail to see why this should not work. I know generic types are not reified, but in both cases it seems to be fully type safe without having access to runtime generic types. Anybody an idea?

推荐答案

泛型是不变的。

Object o = "someString"; // FINE!
Class<Object> klazz = String.class; // DOESN'T COMPILE!
// cannot convert from Class<String> to Class<Object>

根据您的需要,您可以使用通配符。

Depending on what it is that you need, you may be able to use wildcards.

Class<? extends Number> klazz = Integer.class; // FINE!

或许你需要这样的东西:

Or perhaps you need something like this:

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>>






至于运行时未确定的例如,你似乎掌握得很好,但无论如何,这是一个引用,来自关于泛型的Java教程 The Fine Print 通用类由其所有调用共享


以下代码片段是什么打印?

What does the following code fragment print?

List <String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());

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

You might be tempted to say false, but you'd be wrong. It prints true, because all instances of a generic class have the same run-time class, regardless of their actual type parameters.

也就是说,没有 List< String> .class 列表<整数> .class ;只有 List.class

That is, there's no such thing as List<String>.class or List<Integer>.class; there's only List.class.

这也反映在 JLS 15.8.2 Class Literals


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

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

Note the omission of any allowance for generic type parameters/arguments. Furthermore,


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

It is a compile time error if any of the following occur:


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

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

That is, this also doesn't compile:

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

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

Basically you can't use generics with class literals, because it just doesn't make sense: they're non-reified.

这篇关于为什么使用Collection&lt; String&gt; .class非法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆