前言

日常瑣碎的時間下,不適合看一些長篇高質量的文章,但是瑣碎時間也是時間,看一些短小精悍的文章來查缺補漏也是極好的。碎花化的時間,就交給“碎片化的文章”來填充吧。

今天“碎片化文章”主題:泛型-有限通配符。(推薦閱讀5分鐘+3分鐘思考

正文

關於泛型:

上限通配符:<? extends Type>下限通配符:<? super Type>本文解決倆個問題:

1、無限通配符存在的問題2、上下限通配符的不同publicclassTypeTest{publicvoid test(){TypeTest.copy(newArrayList<Object>(),newArrayList<String>());TypeTest.copy(newArrayList<String>(),newArrayList<Object>());}publicstatic<T>void copy(List<?super T> dest,List<?extends T> src){for(int i =0; i < src.size(); i++) dest.set(i, src.get(i));}publicstaticvoid copy2(List<?> dest,List<?> src){for(int i=0; i<src.size(); i++) dest.set(i,src.get(i));}}

大家覺得這個TypeTest類有多少個錯誤?答案是倆個:

1、無限通配符存在的問題

第一個錯誤很簡單:對於List<?>src來說,它的get()可以取出任意類型(Object及其子類),畢竟它是無限通配符修飾。

對於List<?>dest來說,它的set()同樣可以接受任意類型,“貌似”沒有問題?

這裏我們設想代碼可以運行。對於dest和src來說,二者都是任意類型。

如果成功運行的代碼,dest是ArrayList<String>,src是ArrayList<Integer>,在運行期間通過copy2()方法去拷貝dest和src。那麼當dest嘗試get()時一定會崩潰!因爲dest是按自己期望類型String取,但是src可不是按dest的期望類型去存,所以我們一定會在運行期間遇到:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

因此IDE一般會在代碼編寫階段禁止這種問題的出現!

2、上下限通配符的不同

由於上邊提到的“寬鬆的方法簽名”(無限通配符),也就引出了有限通配符,也就是demo代碼中

publicstatic<T>voidcopy(List<?superT>dest,List<?extendsT>src)

裏的實現。

這種寫法就保證了上述的問題:

對於src來說,由於上限通配符的存在,只能 get()或 set()T及T的子類。對於dest來說,由於下限通配符的存在,只能 get()或 set()T及T的父類。在這個例子中,dest作爲輸出集合,get()方法只能得到T及T的父類,那麼只要輸入集合src提供的類型是T及T的子類,那麼對於輸出集合dest就一定沒有問題

這也就是demo代碼中第2個錯誤出現的原因。

注意!!這部分內容只是解釋<?superT>和<?extendsT>的異同幫助大家理解有限通配符,在使用的時候還是要具體情況具體分析。

尾聲

OK,結束的很突然?沒錯就是這麼突然,接下來的時間,大家可以關掉手機花個兩三分鐘想一想剛纔的內容,想明白了,也就有收穫了~

相關文章