Type的定義
/**
* Type is the common superinterface for all types in the Java
* programming language. These include raw types, parameterized types,
* array types, type variables and primitive types.
*
* @since 1.5
*/
public interface Type {}
翻譯成中文,大致如下:
在Java編程語言中干旧,
Type
是所有類型的父接口驹吮。包括:
- 原始類型(raw types),對(duì)應(yīng)
Class
實(shí)現(xiàn)類- 參數(shù)化類型(parameterized types)痰腮,對(duì)應(yīng)
ParameterizedType
接口- 泛型數(shù)組類型(array types),對(duì)應(yīng)
GenericArrayType
接口- 類型變量(type variables)律罢,對(duì)應(yīng)
TypeVariable
接口- 基本類型(primitive types)膀值,對(duì)應(yīng)
Class
實(shí)現(xiàn)類- 通配符類型(wildcard types),對(duì)應(yīng)
WildcardType
接口
一個(gè)簡(jiǎn)單的例子
public class Main {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
Method method = Main.class.getMethod("testType",
List.class, List.class, List.class, List.class, List.class, Map.class);
// 按照聲明順序返回`Type對(duì)象`的數(shù)組
Type[] types = method.getGenericParameterTypes();
for (int i = 0; i < types.length; i++) {
// 最外層都是ParameterizedType
ParameterizedType pType = (ParameterizedType) types[i];
// 返回表示此類型【實(shí)際類型參數(shù)】的`Type對(duì)象`的數(shù)組
Type[] actualTypes = pType.getActualTypeArguments();
for (int j = 0; j < actualTypes.length; j++) {
Type actualType = actualTypes[j];
System.out.print("(" + i + ":" + j + ") 類型【" + actualType + "】");
if (actualType instanceof Class) {
System.out.println(" -> 類型接口【" + actualType.getClass().getSimpleName() + "】");
} else {
System.out.println(" -> 類型接口【" + actualType.getClass().getInterfaces()[0].getSimpleName() + "】");
}
}
}
}
public <T> void testType(List<String> a1,
List<ArrayList<String>> a2,
List<T> a3,
List<? extends Number> a4,
List<ArrayList<String>[]> a5,
Map<String, Integer> a6) {
}
}
執(zhí)行以上代碼误辑,我們得到以下結(jié)果:
(0:0) 類型【class java.lang.String】 -> 類型接口【Class】
(1:0) 類型【java.util.ArrayList<java.lang.String>】 -> 類型接口【ParameterizedType】
(2:0) 類型【T】 -> 類型接口【TypeVariable】
(3:0) 類型【? extends java.lang.Number】 -> 類型接口【W(wǎng)ildcardType】
(4:0) 類型【java.util.ArrayList<java.lang.String>[]】 -> 類型接口【GenericArrayType】
(5:0) 類型【class java.lang.String】 -> 類型接口【Class】
(5:1) 類型【class java.lang.Integer】 -> 類型接口【Class】
類型可能出現(xiàn)的場(chǎng)景
- 修飾類的繼承(extends)或?qū)崿F(xiàn)(implements)關(guān)系類型
- 修飾類的參數(shù)類型
- 修飾字段的類型
- 修飾方法的請(qǐng)求參數(shù)類型
- 修飾方法的返回參數(shù)類型
ParameterizedType
ParameterizedType
沧踏,叫做參數(shù)化類型,也叫泛型巾钉,指的是帶尖括號(hào)的修飾符類型悦冀。例如:List<T>
、Map<Integer, String>
睛琳、List<? extends Number>
盒蟆。
方法 - Type[] getActualTypeArguments();
- 表示此類型實(shí)際類型參數(shù)的
Type對(duì)象
的數(shù)組。 - 也就是說师骗,獲得參數(shù)化類型中
<>
里面的類型參數(shù)的類型历等。 - 可能有多個(gè)類型參數(shù),例如
Map<K, V>
辟癌。
方法 - Type getRawType();
- 返回
Type對(duì)象
寒屯,表示聲明此類型的類或接口。 - 簡(jiǎn)單來說就是:返回最外層
<>
前面那個(gè)類型黍少,例如Map<K ,V>
寡夹,針對(duì)K或V來說,返回的就是Map類型厂置。
方法 - Type getOwnerType();
- 返回Type對(duì)象菩掏,表示此類型是其成員之一的類型。
- 如果當(dāng)前類型為頂層類型昵济,則返回null(通常情況是這樣)智绸。
- 例如:
Map.Entry
中的Entry
返回的就是Map
野揪,A.B.C
中的C
返回的就是A$B
。
例子
public class Main {
public static void main(String[] args) throws Exception {
Method method = Main.class.getMethod("calc", List.class);
Type[] types = method.getGenericParameterTypes();
ParameterizedType listType = (ParameterizedType) types[0];
System.out.println("listType.getRawType() is Class: " + (listType.getRawType() instanceof Class));
System.out.println("listType.getRawType() return: " + listType.getRawType().getTypeName());
ParameterizedType abctType = (ParameterizedType) listType.getActualTypeArguments()[0];
System.out.println("abctType.getOwnerType() is Class: " + (abctType.getOwnerType() instanceof Class));
System.out.println("abctType.getOwnerType() return: " + abctType.getOwnerType());
}
public <T> void calc(List<A.B.C<T>> list) {
}
interface A<T> {
interface B<T> {
interface C<T> {
}
}
}
}
返回結(jié)果如下:
listType.getRawType() is Class: true
listType.getRawType() return: java.util.List
abctType.getOwnerType() is Class: true
abctType.getOwnerType() return: interface com.junconcurrent.Main$A$B
TypeVariable
TypeVariable
瞧栗,叫做類型變量斯稳,泛指任意類。例如:參數(shù)化類型中的E迹恐、K挣惰、V、T等殴边。
方法 - Type[] getBounds();
- 返回表示此類型變量上邊界的
Type對(duì)象
的數(shù)組憎茂。 - 【注意】:如果未顯式聲明上邊界,則上邊界為
Object
找都。 - 【主要】:在類型變量中唇辨,只能有上邊界廊酣,不能有下邊界能耻。例如:
V super Xxx
,將編譯報(bào)錯(cuò)亡驰。
方法 - D getGenericDeclaration();
返回表示聲明此類型變量的泛型聲明的GenericDeclaration
對(duì)象晓猛。
方法 - String getName();
返回此類型變量的名稱,因?yàn)樗霈F(xiàn)在源代碼中凡辱。
方法 - AnnotatedType[] getAnnotatedBounds();
返回AnnotatedType對(duì)象的數(shù)組戒职,這些對(duì)象表示使用類型來表示此TypeVariable表示的類型參數(shù)的上限。
例子
public class Main {
public static void main(String[] args) throws Exception {
Method method = Main.class.getMethod("calc", List.class);
Type[] types = method.getGenericParameterTypes();
ParameterizedType listType = (ParameterizedType) types[0];
System.out.println("listType.getRawType() is Class: " + (listType.getRawType() instanceof Class));
System.out.println("listType.getRawType() return: " + listType.getRawType().getTypeName());
TypeVariable abctType = (TypeVariable) listType.getActualTypeArguments()[0];
System.out.println("abctType.getName() return: " + abctType.getName());
System.out.println("abctType.getBounds() return: " + Arrays.toString(abctType.getBounds()));
System.out.println("abctType.getGenericDeclaration() return: " + abctType.getGenericDeclaration());
}
public <T extends String & Map> void calc(List<T> list) {
}
}
返回結(jié)果如下:
listType.getRawType() is Class: true
listType.getRawType() return: java.util.List
abctType.getName() return: T
abctType.getBounds() return: [class java.lang.String, interface java.util.Map]
abctType.getGenericDeclaration() return: public void com.junconcurrent.Main.calc(java.util.List)
GenericArrayType
GenericArrayType
透乾,叫做泛型數(shù)組類型洪燥,其組件類型為參數(shù)化類型或類型變量。例如:List<T>[]
乳乌、T[]
捧韵。其和一般數(shù)組類型不太一樣。如果方括號(hào)去掉之后的類型是參數(shù)化類型或者類型變量汉操,那么其就是GenericArrayType
再来。否則為一般數(shù)組類型,例如:List[]
磷瘤、String[]
芒篷,其類型為Class
。
方法 - Type getGenericComponentType();
返回表示此數(shù)組的組件類型的Type對(duì)象
采缚。此方法用于獲取數(shù)組的組件類型针炉。
獲取泛型數(shù)組中元素的類型,要注意的是:無論從左向右有幾個(gè)
[]
并列扳抽,這個(gè)方法僅僅脫去最右邊的[]
糊识,之后剩下的內(nèi)容就作為這個(gè)方法的返回值绩社。
WildcardType
WildcardType
為通配符類型表達(dá)式。例如:?
赂苗、? super T
愉耙、? extends T
、? extends Number
拌滋。
方法 - Type[] getUpperBounds();
返回表示此類型變量上邊界的Type對(duì)象的數(shù)組朴沿。
【注意】:如果不存在顯式聲明的上邊界,則上邊界為Object
败砂。
方法 - Type[] getLowerBounds();
返回表示此類型變量下邊界的Type對(duì)象的數(shù)組赌渣。
【注意】:如果不存在顯式聲明的下邊界,則下邊界為類型 null昌犹。在此情況下懒震,將返回長(zhǎng)度為零的數(shù)組。
Class
除了上述4種類型之外激捏,通常的類型或者原始類型武花,都是Class類型。