当类的泛型相关时,如何在两个泛型类之间创建类似子类型的关系呢
作者 | 阿Q
來源 | 阿Q說代碼
事情是這樣的:
對話中的截圖如下:
看了阿Q的解釋,你是否也和“馬小跳”一樣存在疑問呢?請往👇看
我們都知道在java中,只要是類型兼容,就可以將一種類型的對象分配給另一種類型的對象。比如可以將一個Integer類型的對象分配給Object類型的對象,因為Object 是Integer的超類。
Object?someObject?=?new?Object(); Integer?someInteger?=?new?Integer(10); someObject?=?someInteger;?//OK在面向對象中,我們把它稱之為 is a 的關系。因為Integer是Object的一種子類,所以允許被賦值。
又因為Integer也是Number的一種子類,所以下邊的代碼也是有效的:
public?void?someMethod(Number?n)?{?/*?...?*/?}someMethod(new?Integer(10));???//?OK someMethod(new?Double(10.1));???//?OK當然泛型也是如此,在執行泛型類型調用時,將Number作為其類型參數傳遞,如果參數是Number的子類型,則允許任何后續的add調用:
Box<Number>?box?=?new?Box<Number>(); box.add(new?Integer(10));???//?OK box.add(new?Double(10.1));??//?OK現在我們來看以下代碼:
public?void?boxTest(Box<Number>?n)?{?/*?...?*/?}該方法接收什么類型的參數呢?
通過該方法,大家肯定知道它的參數類型為Box<Number>,但是大家思考一個問題:你認為Box<Integer> 和Box<Double>類型的參數可以傳入嗎?
答案是否定的。
盡管Integer是Number的子類型,但Box<Integer> 和Box<Double>不是Box<Number>的子類,它倆的父類對象是Object。文首的對話表達的就是這個意思。
那么問題來了,當類的泛型相關時,如何在兩個泛型類之間創建類似子類型的關系呢?例如如何讓Box<Integer> 和Box<Double>變得與Box<Number>有關呢?
為了搞懂這個問題,我們先來了解一下同一類型的對象是如何實現子類型化的吧。
通過分析源碼我們可以發現:ArrayList<E> 實現了 List<E>,List<E> 繼承了Collection<E>,所以ArrayList<String>是List<String>的子類型, List<String>是 Collection<String>的子類型。因此當我們在傳遞參數時,ArrayList<String>類型的是可以給List<E>或者Collection<E>傳遞的。
只要不改變類型參數,類型之間的子類型關系就會保留。
如果我們想要定義我們自己的列表接口PayloadList,使得泛型類型P的可選值與每個元素相關聯,可以定義如下:
interface?PayloadList<E,P>?extends?List<E>?{void?setPayload(int?index,?P?val);... }則PayloadList<String,String>、PayloadList<String,Integer>、PayloadList<String,Exception>都是List<String>的子類型。
小結:可以通過繼承泛型類或者實現接口來對其進行子類型化。
搞懂了子類型化的問題,我們回到“如何在兩個泛型類之間創建類似子類型的關系“的問題。
泛型類或者接口并不會僅僅因為它們的類型之間有關系而變得相關,如果要達到相關,我們可以使用通配符來創建泛型類或接口之間的關系。
Box<Integer> 和Box<Number>的父類對象其實是Box<?>
為了在這些類之間創建關系,以便代碼可以通過Box<Integer>訪問Box<Number>的方法,可以使用上限通配符:
Box<??extends?Integer>?initBox?=?new?Box<>(); Box<??extends?Number>?numberBox?=?initBox; //?OK.?Box<??extends?Integer>?is?a?subtype?of?Box<??extends?Number>因為Integer是Number的子類型,numberBox的泛型是Number對象子類,所以在intBox和numberBox之間存在關系。
圖為用上限和下限通配符聲明的幾個類之間的關系。
往期推薦
Redis 緩存擊穿(失效)、緩存穿透、緩存雪崩怎么解決?
如果被問到分布式鎖,應該怎樣回答?
三分鐘教你用 Scarlet 寫一個 WebSocket App
Java 底層知識:什么是?“橋接方法”??
點分享
點收藏
點點贊
點在看
總結
以上是生活随笔為你收集整理的当类的泛型相关时,如何在两个泛型类之间创建类似子类型的关系呢的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一行指令造成 60 亿美元蒸发,更让 F
- 下一篇: 超值一篇分享,Docker:从入门到实战