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),对应
Class
实现类- 参数化类型(parameterized types),对应
ParameterizedType
接口- 泛型数组类型(array types),对应
GenericArrayType
接口- 类型变量(type variables),对应
TypeVariable
接口- 基本类型(primitive types),对应
Class
实现类- 通配符类型(wildcard types),对应
WildcardType
接口
一个简单的例子
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对象`的数组
Type[] types = method.getGenericParameterTypes();
for (int i = 0; i < types.length; i++) {
// 最外层都是ParameterizedType
ParameterizedType pType = (ParameterizedType) types[i];
// 返回表示此类型【实际类型参数】的`Type对象`的数组
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) {
}
}
执行以上代码,我们得到以下结果:
(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】 -> 类型接口【WildcardType】
(4:0) 类型【java.util.ArrayList<java.lang.String>[]】 -> 类型接口【GenericArrayType】
(5:0) 类型【class java.lang.String】 -> 类型接口【Class】
(5:1) 类型【class java.lang.Integer】 -> 类型接口【Class】
类型可能出现的场景
- 修饰类的继承(extends)或实现(implements)关系类型
- 修饰类的参数类型
- 修饰字段的类型
- 修饰方法的请求参数类型
- 修饰方法的返回参数类型
ParameterizedType
ParameterizedType
,叫做参数化类型,也叫泛型,指的是带尖括号的修饰符类型。例如:List<T>
、Map<Integer, String>
、List<? extends Number>
。
方法 - Type[] getActualTypeArguments();
- 表示此类型实际类型参数的
Type对象
的数组。 - 也就是说,获得参数化类型中
<>
里面的类型参数的类型。 - 可能有多个类型参数,例如
Map<K, V>
。
方法 - Type getRawType();
- 返回
Type对象
,表示声明此类型的类或接口。 - 简单来说就是:返回最外层
<>
前面那个类型,例如Map<K ,V>
,针对K或V来说,返回的就是Map类型。
方法 - Type getOwnerType();
- 返回Type对象,表示此类型是其成员之一的类型。
- 如果当前类型为顶层类型,则返回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> {
}
}
}
}
返回结果如下:
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
,叫做类型变量,泛指任意类。例如:参数化类型中的E、K、V、T等。
方法 - Type[] getBounds();
- 返回表示此类型变量上边界的
Type对象
的数组。 - 【注意】:如果未显式声明上边界,则上边界为
Object
。 - 【主要】:在类型变量中,只能有上边界,不能有下边界。例如:
V super Xxx
,将编译报错。
方法 - D getGenericDeclaration();
返回表示声明此类型变量的泛型声明的GenericDeclaration
对象。
方法 - String getName();
返回此类型变量的名称,因为它出现在源代码中。
方法 - AnnotatedType[] getAnnotatedBounds();
返回AnnotatedType对象的数组,这些对象表示使用类型来表示此TypeVariable表示的类型参数的上限。
例子
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) {
}
}
返回结果如下:
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
,叫做泛型数组类型,其组件类型为参数化类型或类型变量。例如:List<T>[]
、T[]
。其和一般数组类型不太一样。如果方括号去掉之后的类型是参数化类型或者类型变量,那么其就是GenericArrayType
。否则为一般数组类型,例如:List[]
、String[]
,其类型为Class
。
方法 - Type getGenericComponentType();
返回表示此数组的组件类型的Type对象
。此方法用于获取数组的组件类型。
获取泛型数组中元素的类型,要注意的是:无论从左向右有几个
[]
并列,这个方法仅仅脱去最右边的[]
,之后剩下的内容就作为这个方法的返回值。
WildcardType
WildcardType
为通配符类型表达式。例如:?
、? super T
、? extends T
、? extends Number
。
方法 - Type[] getUpperBounds();
返回表示此类型变量上边界的Type对象的数组。
【注意】:如果不存在显式声明的上边界,则上边界为Object
。
方法 - Type[] getLowerBounds();
返回表示此类型变量下边界的Type对象的数组。
【注意】:如果不存在显式声明的下边界,则下边界为类型 null。在此情况下,将返回长度为零的数组。
Class
除了上述4种类型之外,通常的类型或者原始类型,都是Class类型。
网友评论