簡體   English   中英

為什么我們不能使用擴展邊界在 java 泛型中添加元素?

[英]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

這是因為編譯器無法確定泛型列表的實際類型(在我們的示例中可能是IntegerFloatDouble )。 因此,這是一個不安全的操作,您可能將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.

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