[英]Why in java generics List<Integer> is a subtype of List<? extends Integer>?
在 java 教程中:
https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html
它表示List<Integer>
是List<? extends Integer>
List<? extends Integer>
,我覺得這違反直覺,因為? extends Integer
? extends Integer
表示任何類型是Integer
或Integer
的子類型,這背后的設計考慮是什么?
引用:
https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html
術語
List<Number>
比List<? extends Number>
List<? extends Number>
因為前者只匹配 Number 類型的列表,而后者匹配 Number 類型或其任何子類的列表。
我也對List<? super Number>
List<? super Number>
是List<? super Integer>
List<? super Integer>
。
考慮到List<Dog> 是 List<Animal> 的子類,我很驚訝竟然存在超類型/子類型關系? 為什么 Java generics 不是隱式多態的? . 但是,既然有,我只能冒險自己的想法/猜測為什么它被允許以及為什么這樣。
編輯添加:進一步檢查,我不應該感到驚訝,因為關系與狗和動物相同 - 即。 List<Animal>
是List<? extends Animal>
List<? extends Animal>
。
話雖如此,我想這是為了保持對這些列表的其他引用“安全”。 例如,考慮一些可能的情況:
public class PositiveInteger extends Integer {
那么我們可以有
List<Integer> listInteger = new ArrayList<>();
List<Integer> myIntegers = listInteger;
List<PositiveInteger> listPositiveInteger = new ArrayList<>();
List<PositiveInteger> myPositives = listPositiveInteger;
現在,超類型和子類型的想法是我們可以將子類型引用分配給超類型,但反之則不行。 例如我們可以有:
Animal animal = myDog;
但不是
Dog rex = someAnimal;
因此,讓我們將該邏輯應用於我們的列表。
List<? extends Integer> positives = listInteger;
正如你所說,這是允許的。 需要注意的重要一點是,我們現有的myIntegers
變量是安全的——它仍然只會包含Integer
。
此語句的唯一“危險”是這允許positives.get(0)
可能收到負數 Integer - 但這根本不是真正的危險(只是我們變量命名的問題),因為這里的語言語法僅指對於整數,與 PositiveIntegers 無關。 就語言而言,我們同樣可以:
List<? extends Integer> positives = new ArrayList<NegativeIntegers>();
現在,如果我們允許:
List<Integer> integers = listPositiveInteger;
現在系統的這部分是安全的——但是我們的myPositives
變量呢??? myPositives
的所有用戶都完全有權期望只收到 PositiveIntegers,但沒有什么能阻止我們擁有:
integers.add(-123);
由於這是與 myPositives 相同的列表myPositives
,因此我們將 -123 添加到該列表 - 一個更加危險的前景隱含影響系統的 rest。
為什么在 java generics
List<Integer>
是List<? extends Integer>
List<? extends Integer>
?
因為否則您將無法執行以下操作:
List<Integer> list1 = new ArrayList<>();
List<? extends Integer> list2 = list1;
就個人而言,我會發現上述導致錯誤是反直覺的情況。 當你有List<? extends Integer>
List<? extends Integer>
就是說List
可能包含Integer
, Integer
1的某些子類型,或Integer
的子類型的混合物。 List<Integer>
當然滿足這些要求。
List<? super Number>
List<? super Number>
是List<? super Integer>
List<? super Integer>
非常相似。 如果不是這種情況,那么您將無法執行以下操作:
List<? super Number> list1 = new ArrayList<>();
List<? super Integer> list2 = list1;
所有List<? super Integer>
List<? super Integer>
表示List
能夠使用 Integer 類型的Integer
或Integer
的某些超類型。 一個List<? super Number>
List<? super Number>
滿足這些要求。
以下是一些可能有用的鏈接:
<? super T>
之間的區別 <? super T>
和<? extends T>
在 Java 中<? extends T>
[重復]List<? extends Number>
List<? extends Number>
數據結構?我建議也瀏覽上述問答的鏈接/相關部分。
1. 說“ Integer
的子類型”可能會令人困惑,因為 class 是final
的,但希望它仍然有意義。
試試看? super T
像這樣的? super T
子類型:
<? super Number>
<? super Number>
是<Number>
或<Serializable>
或<Object>
的通配符
<? super Integer>
<? super Integer>
是<Integer>
或<Number>
或<Serializable>
或<Object>
的通配符
Integer
可以放在所有可能的<? super Number>
<? super Number>
所以<? super Integer>
<? super Integer>
可以是<? super Number>
<? super Number>
(是一種關系,所以<? super Number>
是<? super Integer>
的子類型)
Number
不能放在所有可能的<? super Integer>
<? super Integer>
(你不能在Integer
預期的地方放任何Number
)所以<? super Number>
<? super Number>
不能是<? super Integer>
<? super Integer>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.