本文介紹了如何使Java列表協變的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我有以下課程
public class Animal
public class Dog extends Animal
public class Cat extends Animal
對于測試,我有一個驅動程序類。
public class Driver {
public static void main(String[] args){
List<? extends Animal> animalList = Arrays.<Dog>asList(new Dog(), new Dog(), new Dog());
animalList.add(new Dog()) // Compilation error
}
}
默認情況下,列表是不變類型容器。例如,假設我們有List<Object> objectList
,ArrayList<String> stringList
,我們不能將字符串列表替換為objList。這將導致編譯錯誤
我的嘗試是使List成為驅動程序類中的協變。
根據<? extends Animal>
,我們可以應用任何屬于Animal子類型的對象,包括Animal類型。
但我在指定的行中遇到了編譯問題。有沒有人能從理論上解釋一下我哪里錯了。
推薦答案
我認為您誤解了泛型通配符(?
)。來自Java tutorial on the subject:
像往常一樣,使用靈活性是要付出代價的
通配符。這個代價是,現在將文字寫成形狀是非法的
在方法體中。例如,這是不允許的:public void addRectangle(List<? extends Shape> shapes) { // Compile-time error! shapes.add(0, new Rectangle()); }
您應該能夠弄清楚為什么上面的代碼是不允許的。這個
shapes.add()
的第二個參數的類型為? extends Shape
–一個
Shape
的未知子類型。由于我們不知道它是什么類型的,我們
不知道它是否是Rectangle
的超類型;它可能是也可能不是
這樣的超類型,因此在那里傳遞Rectangle
是不安全的。
Java泛型集合不是協變的;有關說明,例如,請參閱Java theory and practice: Generics gotchas。
這篇關于如何使Java列表協變的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,