相關文章推薦
1.https://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java
2.https://howtodoinjava.com/java/generics/java-generics-what-is-pecs-producer-extends-consumer-super/
1.前言
爲什麼學習RxJava還要學習泛型?因爲RxJava裏面用到了大量的泛型,你能看懂嗎?
爲什麼有得是extends 有得是supper 有的是T 有的是 ?接下來我們就來講解下泛型的幾種用法。
2.什麼是PECS
講到泛型就必須要講到PECS(producer-extends-consumer-super)裏面有生產者和消費者的概念。生產者使用extends 消費者使用super。
2.1 泛型的常見寫法
1.extends (上界)
2.supper (下界)
3.T (指定類型)
4.? (通配符)
2.2 extends (只能讀,不能寫)
1.在傳遞的泛型類型可以是extends指定的子類,不能是父類型
2.在泛型種使用extends的時候不能寫入需要傳遞泛型的數據,
下面舉個例子
可以看到 這裏我們使用了通配符<? extends String> 表示 可以傳遞的類型可以是String,以及他的子類型,但是由於這裏我們是使用的extends,導致這裏再使用add方法的時候無法將數據添加到list中,這個list已經不能被修改數據。
根據PECS法則裏面提到,生產者是使用extends,消費者是super,因爲這個list也是從外部傳進來的,
所以如果使用了extends只能讀取使用。就不要用作於修改數據了。
2.3 super (能寫,不能完全讀)
看個例子
2.4 T (類型參數)
一般用作與指定傳遞的類型或者指定返回的類型。常見的寫法有用作於聲明類的時候傳遞和在方法上進行傳遞 比如
class Response<T>{
int reponseCode;
String message;
T t; // 這個T表示返回你傳入進來需要代表的對象
}
還有作用於方法上的用法
2.5 ? (通配符)
如果不確定需要傳遞的數據類型,則可以使用此通配符,如果確定了讀寫都是一樣的數據類型,則可以不用此通配符。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-gBjNGaVo-1572847661209)(12.png)]
可以看到,這裏使用通配符? 能夠傳遞任意類型的數據進去,但是 取數的時候不能獲取到真是的類型,如果想要獲取到真實的類型可以像下面這樣做。
3.總結
頻繁往外讀取內容的,適合用上界extends
經常往裏寫入數據的的,適合用下界super
如果您需要同時滿足這兩個條件,則不要使用任何通配符。
4.另外
數組是不安全的協變。建議儘量採用列表(List)的形式
例子
可以看到,這裏是沒有報錯的,如果運行的話這裏是發生異常的,這種異常在只有在運行的時候才能發現,到那個時候就已經太晚了。
Exception in thread "main" java.lang.ArrayStoreException: java.lang.String
at com.xiaxiayige.rxjavademo.generic.TestGeneric.main(TestGeneric.java:32)