在工做中使用<? extends T>是很常見的。那麼在使用add方法的時候(List <? extends T>),是否是發如今編譯的時候就會報錯。爲何,這是我和同事同時發出的疑問。這看來仍是咱們對JAVA的泛型不是太理解。纔會犯這樣的錯誤。可見JAVA的基礎知識是多麼的重要。java
首先java泛型的出現就是爲了安全,全部的泛型的異常都是在編譯期間發現,因此在設計的時候作了相關限制。安全
- <? extends T>:好比在List<? extends T>,表示該list集合中存放的是T和T的子類型,因爲T的子類可能不少(java是單繼承,繼承的類構成了一棵樹),那麼T就是根,下面不少的子,不一樣的子是不兼容的,在集合中存放的元素只能是子類中的其中一種。若是java准許add方法,那麼只要是T和T的子類均可以向list集合裏面添加,這樣在編譯的時候就會強制轉換失敗(不能把麻雀強制轉換成鳳凰),或者說是編譯器根本不知道應該轉換成什麼類型,因此不能添加元素;雖然不能添加元素,可是其中的元素都是T的子類(有共同的父類),所以在get方法的時候,能夠強制轉換成T(向上轉型),因此獲取元素是能夠的。
- <? super T>:好比List<? super T>,表示該list集合中存放的是T和T的父類,再向list集合中添加元素,只能添加T和T的子類,這樣在編譯期間將其強制轉換成T是類型安全的。可是集合中的元素都是T或者是T的父類,在get元素時候,編譯器沒法判斷是哪一種類型,所以設計成不能get元素。
在java的泛型中使用extends和super就是爲了彌補list<T>的不足(只能存放一種類型的元素),這樣在get和add的時候均可以使用多種類型的元素。設計