簡體   English   中英

泛型 - 無法添加到具有無界通配符的列表

[英]Generics - Cannot add to a List with unbounded wildcard

我實例化以下列表:

// I am just revising generics again and the following is just cursory code!
List<? super Integer> someList = new ArrayList<Object>();
someList.add(new Object());

以上不起作用。 我收到編譯器錯誤。 但是,以下工作:

List<? super Integer> someList = new ArrayList<Object>();
someList.add(11);

我知道您可以將對象添加到包含無界通配符的集合中,而不是有界通配符。

但是,為什么以上不起作用? Object是Integer的超類型,為什么我不能添加它?

這聲明它是一個超類型的東西的列表,而不是列表可以包含任何超類型的整數。 換句話說,對於編譯器,它可以是List<Integer>List<Number>List<Object> ,但它不知道哪個,因此您不能向List添加任何內容。 你唯一可以安全添加的是Integer,因為它保證是List可能擁有的任何類型的子類型。

換句話說, ? 代表一種類型,而不是任何類型。 這是一個非顯而易見但重要的區別。

對於變量someList ,所有編譯器/語言必須使用的是靜態類型List<? super Integer> List<? super Integer> 它可能是從List<Integer>分配的。 顯然,您不希望向List<Integer>添加new Object()

你可以向List<? super Integer>添加null List<? super Integer> List<? super Integer> ,您可以將列表傳遞給另一個捕獲泛型類型的方法,因此可以在列表周圍移動引用(方法,如Collections.shuffle )。

一個List<? super Integer> List<? super Integer>不是包含任何超類型Integer任何元素的列表(這也沒有意義),但是列表是一個具體的未知元素類型,它是Integer的超類型。 因此,如果要添加的元素是正確的具體類型,編譯器就沒有機會確定。

元素類型中具有通配符的任何集合本身都不可擴展,但它們是可修改的(您可以刪除元素或清除整個列表)。

當編譯器遇到someList.add(new Object()) ,它不記得你如何實例化someList 編譯器的所有信息都是如何聲明someList ,即List<? super Integer> someList List<? super Integer> someList 因為您可以通過其中任何一個實例化someList

someList = new ArrayList<Object>()

要么

someList = new ArrayList<Integer>()

並且編譯器不知道它是哪一個,因此編譯器不允許你做someList.add(new Object())因為someList可能是List<Integer>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM