【Java】泛型的類別

今天我們不講泛型的來龍去脈栖雾,講講泛型到底有哪些類別,也就是Type這個接口到底有多少不同的實現(xiàn)(jdk中)

大家可能會疑惑,泛型還能有多種不同的類型村怪?

這不是我前段時間寫了一個庫【Java】簡單優(yōu)雅的加載外部 jar 中的 Class|插件化

在這個庫中我需要實現(xiàn)一個功能:通過泛型來推導(dǎo)數(shù)據(jù)類型來加載對應(yīng)的插件內(nèi)容

于是我就對我們平時常用的泛型做了一些研究

如果大家之前有去了解過相關(guān)的內(nèi)容,就會知道Type接口會有一些不同的實現(xiàn)(jdk中)

  • Class
  • TypeVariable
  • ParameterizedType
  • WildcardType
  • GenericArrayType

那么今天我們就來看看這些類型都對應(yīng)了什么寫法的泛型

Class

首先Class我們接觸的比較多浮庐,雖然實現(xiàn)了Type接口甚负,但不是泛型,就是普通的類的類型审残,并不具有泛型的一些參數(shù)屬性

TypeVariable

可變類型梭域,可以得到最原始的類型信息

如我們常用的ArrayList<E>

我們可以通過getTypeParameters來獲得他的泛型信息

ArrayList.class.getTypeParameters();

但是我們只能拿到E,拿不到具體的類型搅轿,畢竟實例化之后任意的類型都有可能

那么有沒有能拿到具體類型的泛型呢病涨,我們繼續(xù)往下看

ParameterizedType

參數(shù)化類型,可以獲得< >中定義的具體類型

假設(shè)我們繼承ArrayList并指定泛型為String

public class StringArrayList extends ArrayList<String> {
}

這種情況下璧坟,我們就可以使用getGenericSuperclass來獲得泛型信息

StringArrayList.class.getGenericSuperclass();

調(diào)用上面的方法我們就能得到一個ParameterizedType

通過ParameterizedType#getRawType()就可以獲得ArrayList.class

通過ParameterizedType#getActualTypeArguments()就可以獲得String.class

ParameterizedType type = (ParameterizedType) StringArrayList.class.getGenericSuperclass();

Type rawType = type.getRawType();
System.out.println(rawType);
//輸出 class java.util.ArrayList

Type actualTypeArgument = type.getActualTypeArguments()[0];
System.out.println(actualTypeArgument);
//輸出 class java.lang.String

WildcardType

通配符類型既穆,可以獲得泛型的類型界限

主要通過? extends? super約束

舉個例子

public class ClassArrayList extends ArrayList<Class<? extends Serializable>> {
}

其中? extends Serializable就是WildcardType

這里需要注意的是不帶< >

通過WildcardType#getUpperBounds()就可以獲得Serializable.class

ParameterizedType type = (ParameterizedType) ClassArrayList.class.getGenericSuperclass();

Type rawType = type.getRawType();
System.out.println(rawType);
//輸出 class java.util.ArrayList

ParameterizedType actualTypeArgument = (ParameterizedType) type.getActualTypeArguments()[0];
System.out.println(actualTypeArgument);
//輸出 java.lang.Class<? extends java.io.Serializable>

Type argumentRawType = actualTypeArgument.getRawType();
System.out.println(argumentRawType);
//輸出 class java.lang.Class

WildcardType argumentActualTypeArgument = (WildcardType) actualTypeArgument.getActualTypeArguments()[0];
System.out.println(argumentActualTypeArgument);
//輸出 ? extends java.io.Serializable

Type upperBound = argumentActualTypeArgument.getUpperBounds()[0];
System.out.println(upperBound);
//輸出 interface java.io.Serializable

GenericArrayType

泛型數(shù)組類型,表示泛型類型的數(shù)組類型

修改一下上面的例子

public class ClassesArrayList extends ArrayList<Class<? extends Serializable>[]> {
}

實際上就是在原本的泛型類型外又包了一層

ParameterizedType type = (ParameterizedType) ClassesArrayList.class.getGenericSuperclass();

Type rawType = type.getRawType();
System.out.println(rawType);
//輸出 class java.util.ArrayList

GenericArrayType actualTypeArgument = (GenericArrayType) type.getActualTypeArguments()[0];
System.out.println(actualTypeArgument);
//輸出 java.lang.Class<? extends java.io.Serializable>[]

ParameterizedType genericComponentType = (ParameterizedType) actualTypeArgument.getGenericComponentType();
System.out.println(genericComponentType);
//輸出 java.lang.Class<? extends java.io.Serializable>

Type argumentRawType = genericComponentType.getRawType();
System.out.println(argumentRawType);
//輸出 class java.lang.Class

WildcardType argumentActualTypeArgument = (WildcardType) genericComponentType.getActualTypeArguments()[0];
System.out.println(argumentActualTypeArgument);
//輸出 ? extends java.io.Serializable

Type upperBound = argumentActualTypeArgument.getUpperBounds()[0];
System.out.println(upperBound);
//輸出 interface java.io.Serializable

沒見過的泛型寫法

接下來再說一個我在查資料時見到的一種泛型寫法

public class Custom<T extends Serializable & Cloneable> {
}

不知道大家之前有沒有遇到過這樣的寫法

然后我就研究了一下雀鹃,發(fā)現(xiàn)這其實就是一個AND條件

上面的接口表示幻工,這個泛型必須要實現(xiàn)SerializableCloneable,兩個都要滿足

所以比如ArrayList就是可以的:Custom<ArrayList>

而且泛型中的條件可以有多個黎茎,但是最多只能有一個類囊颅,其他必須為接口

可以猜想是java只能繼承一個父類但是可以實現(xiàn)多個接口的原因

那么今天的內(nèi)容就是這樣啦

其他的文章

【Java】簡單優(yōu)雅的加載外部 jar 中的 Class|插件化

【Spring Boot】一個注解實現(xiàn)下載接口

【拿來吧你】JDK動態(tài)代理

【Java】異步回調(diào)轉(zhuǎn)為同步返回

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市工三,隨后出現(xiàn)的幾起案子迁酸,更是在濱河造成了極大的恐慌,老刑警劉巖俭正,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奸鬓,死亡現(xiàn)場離奇詭異,居然都是意外死亡掸读,警方通過查閱死者的電腦和手機串远,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來儿惫,“玉大人澡罚,你說我怎么就攤上這事∩銮耄” “怎么了留搔?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铛铁。 經(jīng)常有香客問我隔显,道長却妨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任括眠,我火速辦了婚禮彪标,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘掷豺。我一直安慰自己捞烟,他們只是感情好,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布当船。 她就那樣靜靜地躺著题画,像睡著了一般。 火紅的嫁衣襯著肌膚如雪德频。 梳的紋絲不亂的頭發(fā)上婴程,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機與錄音抱婉,去河邊找鬼档叔。 笑死,一個胖子當著我的面吹牛蒸绩,可吹牛的內(nèi)容都是我干的衙四。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼患亿,長吁一口氣:“原來是場噩夢啊……” “哼传蹈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起步藕,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤惦界,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后咙冗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沾歪,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年雾消,在試婚紗的時候發(fā)現(xiàn)自己被綠了灾搏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡立润,死狀恐怖狂窑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情桑腮,我是刑警寧澤泉哈,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響丛晦,放射性物質(zhì)發(fā)生泄漏巨缘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一采呐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧搁骑,春花似錦斧吐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乏冀,卻和暖如春蝶糯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辆沦。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工昼捍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肢扯。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓妒茬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蔚晨。 傳聞我的和親對象是個殘疾皇子乍钻,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容