Java 類型總結(jié)


title: Java Type 總結(jié)
date: 2022/06/24 16:44


Java 類型總結(jié)

Type及其子接口的來歷:

泛型出現(xiàn)之前的類型:沒有泛型的時候鹤耍,只有原始類型浊闪。此時有巧,所有的原始類型都通過字節(jié)碼文件類Class類進行抽象。Class類的一個具體對象就代表一個指定的原始類型残拐。

泛型出現(xiàn)之后的類型:泛型出現(xiàn)之后刹孔,擴充了數(shù)據(jù)類型迅栅。從只有原始類型擴充了參數(shù)化類型时呀、類型變量類型张漂、限定符類型 晶默、泛型數(shù)組類型谨娜。

java.lang.reflect.Type 有很多的子類,接下來一個個看一下磺陡。

名稱 描述 示例(以 Field 為例)
Class 最常見的類型趴梢,代表一切沒有泛型的類型 Object、List币他、Map坞靶、Object[]
ParameterizedType 參數(shù)化類型,代表具有泛型的類型 Map<K, V>蝴悉、List<String>
TypeVariable 類型變量彰阴,就是泛型 T、F extends Object
WildcardType 通配符類型拍冠,代表 ? ?尿这、? super String、? extends Object
GenericArrayType 通用數(shù)組類型 T[]庆杜、List<T>[]射众、List<String>[]
image.png

ParameterizedType

只有擁有泛型的類才會是這個類型

測試代碼:

@Test
public void test() {
  Field field = ReflectionUtils.findField(TestParameterizedType.class, "map");
  ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
  System.out.println(Arrays.toString(parameterizedType.getActualTypeArguments()));  // [class java.lang.String, TypeVariable F]
  System.out.println(parameterizedType.getRawType());   // interface java.util.Map
  System.out.println(parameterizedType.getOwnerType()); // null
}

static class TestParameterizedType<F extends Serializable> {
  Map<String, F> map;
}
方法名 描述 測試結(jié)果
parameterizedType.getActualTypeArguments() 返回這個 Type 類型的參數(shù)的實際類型數(shù)組。 如 Map<String, Person> map 這個 ParameterizedType 返回的是 String 類,Person 類的全限定類名的 Type Array晃财。 [class java.lang.String, TypeVariable F]
parameterizedType.getRawType() 返回的是當(dāng)前這個 ParameterizedType 的類型叨橱。 如 Map<String, Person> map 這個 ParameterizedType 返回的是 Map 類的全限定類名的 Type。 interface java.util.Map
parameterizedType.getRawType() 返回的是這個 ParameterizedType 所在的類的 Type 断盛。解釋起來有點別扭罗洗,還是直接用代碼說明吧。 比如 Map<String,Person> map 這個 ParameterizedType 的 getOwnerType() 為 null钢猛,而 Map.Entry<String, String>entry 的 getOwnerType() 為 Map 所屬于的 Type伙菜。 null

TypeVariable

參數(shù)類型,代表泛型參數(shù)

測試代碼:

@Test
public void test() {
    Field field = ReflectionUtils.findField(TestParameterizedType.class, "map");
    ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();// Map
    TypeVariable<Class<?>> typeVariable = (TypeVariable<Class<?>>) parameterizedType.getActualTypeArguments()[1];
    System.out.println(typeVariable.getName()); // F
    System.out.println(Arrays.toString(typeVariable.getBounds()));   // [interface java.io.Serializable]
    System.out.println(typeVariable.getGenericDeclaration());   // class ATest$TestParameterizedType

    Method testMethod = ReflectionUtils.findMethod(TestParameterizedType.class, "testMethod", Class.class);
    ParameterizedType methodParameterType = (ParameterizedType) new MethodParameter(testMethod, 0).getNestedGenericParameterType();
    TypeVariable actualTypeArgument = (TypeVariable) methodParameterType.getActualTypeArguments()[0];
    System.out.println(actualTypeArgument.getName()); // T
    System.out.println(Arrays.toString(actualTypeArgument.getBounds()));   // [class java.lang.Object]
    System.out.println(actualTypeArgument.getGenericDeclaration());   // Method public static void ATest$TestParameterizedType.testMethod(java.lang.Class)
}

static class TestParameterizedType<F extends Serializable> {
    Map<String, F> map;

    public static <T> void testMethod(Class<T> tClass) {
    }
}
方法名 描述 測試結(jié)果
typeVariable.getName() 泛型定義的名稱 F
typeVariable.getBounds() 得到上邊界的 Type 數(shù)組厢洞,如 F 的上邊界數(shù)組是 Serializable仇让。 T 沒有指定的話,上邊界是 Object [class java.lang.Object]
typeVariable.getGenericDeclaration() 聲明這個泛型的地方躺翻,可以聲明泛型的地方有:Class丧叽、Method、構(gòu)造 public static void ATest$TestParameterizedType.testMethod(java.lang.Class)

WildcardType

通配符類型

@Test
public void testWildcardType() {
    Field a = ReflectionUtils.findField(WildcardTypeCls.class, "a");
    WildcardType aType = (WildcardType) ((ParameterizedType) a.getGenericType()).getActualTypeArguments()[0];
    System.out.println(aType.getTypeName());    // ? extends java.lang.Number
    System.out.println(Arrays.toString(aType.getLowerBounds()));    // []
    System.out.println(Arrays.toString(aType.getUpperBounds()));    // [class java.lang.Number]

    Field b = ReflectionUtils.findField(WildcardTypeCls.class, "b");
    WildcardType bType = (WildcardType) ((ParameterizedType) b.getGenericType()).getActualTypeArguments()[0];
    System.out.println(bType.getTypeName());    // ? extends T
    System.out.println(Arrays.toString(bType.getLowerBounds()));    // []
    System.out.println(Arrays.toString(bType.getUpperBounds()));    // [TypeVariable T]

    Field c = ReflectionUtils.findField(WildcardTypeCls.class, "c");
    WildcardType cType = (WildcardType) ((ParameterizedType) c.getGenericType()).getActualTypeArguments()[0];
    System.out.println(cType.getTypeName());    // ? super java.lang.String
    System.out.println(Arrays.toString(cType.getLowerBounds()));    // [class java.lang.String]
    System.out.println(Arrays.toString(cType.getUpperBounds()));    // [class java.lang.Object]
}

static class WildcardTypeCls<T> {
    // 沒有下邊界公你,上邊界為 Number
    private List<? extends Number> a;

    // 上邊界為 T
    private List<? extends T> b;

    // 沒有指定的話踊淳,上邊界默認(rèn)是 Object,下邊界是 String
    private List<? super String> c;
}
方法名 描述 測試結(jié)果
wildcardType.getLowerBounds() 獲取下邊界 [class java.lang.String]
wildcardType.getUpperBounds() 獲取上邊界 [class java.lang.Object]

GenericArrayType

泛型數(shù)組類型。

Generic:通用迂尝,在這里代表泛型的意思脱茉,詳見泛型出現(xiàn)是為了解決啥問題的。

測試代碼:

@Test
public void testGenericArrayType() {
    Field eArray = ReflectionUtils.findField(GenericArrayTypeCls.class, "eArray");
    System.out.println(((GenericArrayType) eArray.getGenericType()).getGenericComponentType()); // TypeVariable E

    Field eListArray = ReflectionUtils.findField(GenericArrayTypeCls.class, "eListArray");
    System.out.println(((GenericArrayType) eListArray.getGenericType()).getGenericComponentType()); // ParameterizedType List<E>  E - TypeVariable

    Field wildcardListArray = ReflectionUtils.findField(GenericArrayTypeCls.class, "wildcardListArray");
    System.out.println(((GenericArrayType) wildcardListArray.getGenericType()).getGenericComponentType()); // ParameterizedType List<?>  ? - WildcardType

    Field stringListArray = ReflectionUtils.findField(GenericArrayTypeCls.class, "stringListArray");
    System.out.println(((GenericArrayType) stringListArray.getGenericType()).getGenericComponentType());    // ParameterizedType List<String>  String - Class

    Field stringArray = ReflectionUtils.findField(GenericArrayTypeCls.class, "stringArray");
    System.out.println(stringArray.getGenericType());   // 這個不是 GenericArrayType 類型垄开。class [Ljava.lang.String;
}

static class GenericArrayTypeCls<E> {
    E[] eArray;
    List<E>[] eListArray;
    List<?>[] wildcardListArray;
    List<String>[] stringListArray;

    // 這個不是
    String[] stringArray;
}
方法名 描述 測試結(jié)果
genericArrayType.getGenericComponentType() 獲取數(shù)組中具體組件的類型 ParameterizedType List<E> E - TypeVariable
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末琴许,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子溉躲,更是在濱河造成了極大的恐慌榜田,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锻梳,死亡現(xiàn)場離奇詭異箭券,居然都是意外死亡,警方通過查閱死者的電腦和手機疑枯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門辩块,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人荆永,你說我怎么就攤上這事废亭。” “怎么了屁魏?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵滔以,是天一觀的道長。 經(jīng)常有香客問我氓拼,道長你画,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任桃漾,我火速辦了婚禮坏匪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撬统。我一直安慰自己适滓,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布恋追。 她就那樣靜靜地躺著凭迹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪苦囱。 梳的紋絲不亂的頭發(fā)上嗅绸,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音撕彤,去河邊找鬼鱼鸠。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蚀狰。 我是一名探鬼主播愉昆,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼麻蹋!你這毒婦竟也來了跛溉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤哥蔚,失蹤者是張志新(化名)和其女友劉穎倒谷,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糙箍,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年牵祟,在試婚紗的時候發(fā)現(xiàn)自己被綠了深夯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡诺苹,死狀恐怖咕晋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情收奔,我是刑警寧澤掌呜,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站坪哄,受9級特大地震影響质蕉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜翩肌,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一模暗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧念祭,春花似錦兑宇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至站玄,卻和暖如春枚驻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蜒什。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工测秸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓霎冯,卻偏偏與公主長得像铃拇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子沈撞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355