【问题标题】:incompatible types: SomeX cannot be converted to CAP#1 [duplicate]不兼容的类型:SomeX 无法转换为 CAP#1 [重复]
【发布时间】:2017-02-02 17:51:43
【问题描述】:

我不明白这里出了什么问题

import java.util.*;

class Main {
    private static class SomeX {}

    void doSomethingWithX(SomeX someX) {
        Collection<? extends SomeX> colectionOfX = new ArrayList<>();
        colectionOfX.add(someX);
    }
}

javac 说如下:

  Main.java:8: error: method add in interface Collection<E> cannot be applied to given types;
          colectionOfX.add(someX);
                      ^
    required: CAP#1
    found: SomeX
    reason: argument mismatch; SomeX cannot be converted to CAP#1
    where E is a type-variable:
      E extends Object declared in interface Collection
    where CAP#1 is a fresh type-variable:
      CAP#1 extends SomeX from capture of ? extends SomeX

据我了解,extends 将 CAP#1 的下限限制为 SomeXSomeX 本身应该满足该限制。

怎么了? (用javac 1.8.0_102编译)

【问题讨论】:

    标签: java generics


    【解决方案1】:

    如果您想允许colectionOfX 包含SomeX 的任何实例,则应将其声明为:

    Collection<SomeX> colectionOfX = new ArrayList<>();
    

    当你声明为

    Collection<? extends SomeX> colectionOfX = ...;
    

    这意味着您可以将任何 Collection 分配给它,该 Collection 包含某种类型的元素,即 SomeXSomeX 的子类。

    例如,您可以为其分配一个List&lt;SomeBX&gt;,其中SomeBX 扩展了SomeX。在这种情况下,只能将 SomeBX 的实例添加到集合中。 因此,如果您尝试将不是SomeBXSomeX 实例添加到集合中(例如,SomeAX 的实例,它也是SomeX 的子类),它将是无效的。

    【讨论】:

    • 所以......所有这些都不能回答“为什么我不能将instance of SomeX 添加到Collection&lt;? extends SomeX&gt;”的问题。该特定操作有什么问题?
    • @XtraCoder 正如我试图解释的那样,Collection&lt;? extends SomeX&gt; colectionOfX 并不接受SomeX 的所有实例。即使您分配给它new ArrayList&lt;SomeX&gt;(),您应该能够向其中添加SomeX 的任何实例,编译器也无法知道这一点,因为它只依赖于编译时类型,即Collection&lt;? extends SomeX&gt;
    【解决方案2】:

    所以,这个问题实际上已经在“How can I add to List<? extends Number> data structures?”中得到了回答,但是谷歌搜索并没有找到匹配项。

    据我所知,简短的答案如下:

    class Main {
        private static class SomeX {}
    
        private static class SomeY extends SomeX {}
    
        void doSomethingWithX(SomeX someX) {
            Collection<? extends SomeX> colectionOfX = new ArrayList<SomeY>();
            colectionOfX.add(someX);
        }
    }
    

    因为&lt;? extends SomeX&gt; 是集合类型的下限而不是项目类型 - 可以为集合的实例分配更高的值,考虑到这一点,将 SomeX 放入此类集合不是类型- 从编译器的角度来看是安全的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      相关资源
      最近更新 更多