【问题标题】:Why are these inherited types used as parameterized types incompatible types?为什么这些继承的类型被用作参数化类型不兼容的类型?
【发布时间】:2012-10-22 18:44:29
【问题描述】:

我对参数化集合的理解是,如果你想使用参数化类型的子类型,你需要将集合声明为Collection<? extends Whatever>

例如:

public interface Fruit {}
public interface Banana extends Fruit {}

void thisWorksFine() {
  //Collection<Fruit> fruits;          //wrong
  Collection<? extends Fruit> fruits;  //right
  Collection<Banana> bananas = new ArrayList<>();
  fruits = bananas;
}

但是如果我添加一个额外的层,这会爆炸:

public interface Box<T> {}

void thisDoesNotCompile() {
    Collection<Box<? extends Fruit>> boxes;
    Collection<Box<Banana>> bananaBoxes = new ArrayList<>();
    boxes = bananaBoxes;  // error!
}

出现错误:

error: incompatible types
required: Collection<Box<? extends Fruit>>
found:    Collection<Box<Banana>>

为什么这些不兼容?有什么办法可以让它工作吗?

【问题讨论】:

    标签: java generics inheritance collections


    【解决方案1】:

    因为您可以在boxes 中添加Box&lt;Apple&gt;,这将违反bananaBoxes 的完整性。

    public interface Apple extends Fruit {}
    
    //...
    
    Box<Apple> apples = new Box<>(); // this is legal
    Box<? extends Fruit> fruits = apples; // this is legal
    
    Collection<Box<Banana>> bananaBoxes = new ArrayList<>(); 
    
    Collection<Box<? extends Fruit>> boxes = bananaBoxes; //if this were legal...
    boxes.add(fruits); //then this would be legal
    
    //and this would be a type violation:
    Box<Banana> bananas = bananaBoxes.iterator().next(); 
    

    你可以这样做

    Collection<? extends Box<? extends Fruit>> boxes = bananaBoxes;
    

    这是合法的,因为它可以防止上述情况。

    【讨论】:

      猜你喜欢
      • 2018-05-29
      • 2020-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-07
      • 2020-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多