![](/img/trans.png)
[英]java generics - “extends” keyword -> not supporting add elements
[英]Why we cant add the elements in java generics using extends bounds?
我知道我們不能在列表中添加擴展邊界類型的元素。 但我仍然不確定為什么 java 編譯器不允許這樣做。 因為編譯器可以很容易地檢查添加的新元素是否是 Generic 類型的子類型。 任何人都可以幫我解決這個問題嗎?
這種情況稱為協方差, extends
關鍵字允許您從Collection
讀取元素,但不能添加它們。 這是因為編譯器將add
操作視為不安全。 例如,您可以聲明以下任何列表:
List<? extends Number> myNums = new ArrayList<Integer>();
List<? extends Number> myNums = new ArrayList<Float>();
List<? extends Number> myNums = new ArrayList<Double>();
您可以毫無問題地讀取它們,因為無論列表包含什么,都可以向上轉換為Number
。 但是,您不得將任何內容放入其中:
myNums.add(45L); //compiler error
這是因為編譯器無法確定泛型列表的實際類型(在我們的示例中可能是Integer
、 Float
或Double
)。 因此,這是一個不安全的操作,您可能將Long
添加到Integer
列表,因此編譯器不允許您這樣做。
閱讀這篇文章以獲得更深入的解釋。
我將使用對這里示例的修改:
List<String> ls = new ArrayList<String>();
List<? extends Object> l = ls;
l.add(l, new Object()); // not legal - but assume it was!
String s = ls.get(0); // ClassCastException - ls contains
// Objects, not Strings.
您非常正確地指出“編譯器可以輕松檢查添加的新元素是否是泛型類型的子類型”。 但即便如此,由於編譯器無法確定列表l
的類型,接受l.add(l, new Object())
將導致列表ls
損壞。
因此編譯器正在做它的工作,它比運行時檢查更早地捕獲錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.