2012-10-22 72 views
1

我與參數的集合明白,如果你要使用參數化類型的子類型,你需要聲明的集合作爲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>> 

爲什麼這些不兼容?有什麼辦法讓這個工作?

回答

4

因爲您可以添加Box<Apple>boxes,這會違反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; 

這是合法的,因爲它可以防止上述情況。