【问题标题】:Generics cast issue泛型演员问题
【发布时间】:2011-11-11 12:07:42
【问题描述】:

这是我的问题:鉴于这些类

class A {}
class B extends A {}

这段代码编译:

    List<Class<? extends A>> list = Arrays.asList(B.class, A.class);

这不是:

    List<Class<? extends A>> anotherList = Arrays.asList(B.class);

什么给了?


更新:此代码在 Java 8 中编译。显然,由于“改进的类型推断”。

【问题讨论】:

  • 第一行没有为我编译

标签: java generics


【解决方案1】:

在第一个示例中,Arrays.asList() 调用的推断类型是 List&lt;Class&lt;? extends A&gt;&gt;,这显然可以分配给相同类型的变量。

在第二个例子中,右边的类型是List&lt;Class&lt;B&gt;&gt;Class&lt;B&gt; 可分配给Class&lt;? extends A&gt;List&lt;Class&lt;B&gt;&gt; 不可分配给List&lt;Class&lt;? extends A&gt;&gt;。它可以分配给List&lt;? extends Class&lt;? extends A&gt;&gt;

原因与List&lt;B&gt; 不能分配给List&lt;A&gt; 的原因相同。如果是这样,它将使以下(非类型安全)代码成为可能:

List<Class<B>> bb = new ArrayList<B>();
List<Class<? extends A>> aa = bb;
aa.add(A.class);

【讨论】:

【解决方案2】:

这将编译:

List<Class<? extends A>> numbers = Arrays.<Class<? extends A>>asList(B.class);

【讨论】:

  • +1 这是正确的解决方案。显式指定参数,因为它与推断的不同
【解决方案3】:
Arrays.asList(B.class);

被泛化为

List<Class<B>> numbers = Arrays.asList(B.class);

因为它只有 1 个类型为 T 的属性与参数化类型匹配(在本例中为 B.class)。

【讨论】:

  • 能否请您指点 JLS 或 Sun 教程,我可以在那里阅读它?
【解决方案4】:

该死的好问题,我不知道答案,但这里有一个解决方法:

List<Class<? extends A>> numbers = new ArrayList<Class<? extends A>>(Arrays.asList(B.class));

【讨论】:

    【解决方案5】:

    只是补充一下,我们可以重写代码如下

    List<Class<? extends A>> asListA = Arrays.asList(B.class, A.class);
    List<Class<B>> asListB = Arrays.asList(B.class);
    
    List<Class<? extends A>> numbers = asListA;
    List<Class<? extends A>> numbers2 = asListB; // it will fail here
    

    @Inerdia 已经解释了细节。

    【讨论】:

      【解决方案6】:

      这是泛型中的协方差/逆变问题。以下 SO 问题应该可以帮助您理解和解决问题:

      Demonstrate covariance and contravariance in Java?

      How would contravariance be used in Java generics?

      【讨论】:

        猜你喜欢
        • 2018-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多