文章目录
- Type简介
- Type分类
- 1. 原始类型(Class)
- 2. 参数化类型(ParameterizedType)
- 3. 类型变量(TypeVariable)
- 4. 通配符类型(WildcardType)
- 5. 泛型数组类型(GenericArrayType)
Type简介
Type是Java编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
Type接口本身算是一个标记接口,不提供任何需要复写的方法。
Type分类
Type分类:
Type分类名称 | Type类型 | 描述 | 举例 |
---|---|---|---|
原始类型 | Class | Java类、枚举、数组、注解、所有基本数据类型 | String、Date、Integer、int、boolean 等 |
参数化类型 | ParameterizedType | 参数化类型(泛型类型) | List<String>、Map<Integer,String>、List<T>、List<?>、List<? extends Number>、List<? super Number> 等 |
类型变量 | TypeVariable | 泛型符号(不包括通配符) | T、K、V、E 等 |
通配符类型 | WildcardType | 通配符 | ?、? extends Number、? super Number 等 |
泛型数组类型 | GenericArrayType | 泛型数组 | List<?>[]、List<T>[]、List<String>[]、List<? extends Number>[]、T[] 等 |
获取Type:
JDK的Class、Field、Method类提供了一些列的获取类型的相关方法。
可参考文章:Java中如何获取泛型类型信息
1. 原始类型(Class)
原始类型的Type实现类为Class。这个类型与泛型无关,其它4个类型都和泛型相关。
原始类型主要包括:Java类、枚举、数组、注解、所有基本数据类型。
示例:
public class TypeTest {
private String string;
private Integer integer;
private long lon;
private int[] intArr;
public static void main(String[] args) throws Exception {
System.out.println(TypeTest.class.getDeclaredField("string").getGenericType() instanceof Class ? "String:是原始类型" : "String:不是原始类型");
System.out.println(TypeTest.class.getDeclaredField("integer").getGenericType() instanceof Class ? "Integer:是原始类型" : "Integer:不是原始类型");
System.out.println(TypeTest.class.getDeclaredField("lon").getGenericType() instanceof Class ? "long:是原始类型" : "long:不是原始类型");
System.out.println(TypeTest.class.getDeclaredField("intArr").getGenericType() instanceof Class ? "int[]:是原始类型" : "int[]:不是原始类型");
}
}
输出:
String:是原始类型
Integer:是原始类型
long:是原始类型
int[]:是原始类型
2. 参数化类型(ParameterizedType)
参数化类型的Type实现类为ParameterizedType。
参数化类型也就是泛型类型。
源码:
public interface ParameterizedType extends Type {
Type[] getActualTypeArguments();
Type getRawType();
Type getOwnerType();
}
方法:
- getActualTypeArguments:获取实际类型参数的Type集合
- getRawType:获取声明此类型的类或接口的Type
- getOwnerType:如果声明此类型的类或接口为内部类,这返回的是该内部类的外部类的Type(也就是该内部类的拥有者)
示例:
public class TypeTest<T> {
private Map<Integer,String> map;
private List<String> list1;
private List<T> list2;
private List<?> list3;
private List<? extends Number> list4;
public static void main(String[] args) throws Exception {
System.out.println(TypeTest.class.getDeclaredField("map").getGenericType() instanceof ParameterizedType ? "Map<Integer,String>:是参数化类型" : "Map<Integer,String>:不是参数化类型");
System.out.println(TypeTest.class.getDeclaredField("list1").getGenericType() instanceof ParameterizedType ? "List<String>:是参数化类型" : "List<String>:不是参数化类型");
System.out.println(TypeTest.class.getDeclaredField("list2").getGenericType() instanceof ParameterizedType ? "List<T>:是参数化类型" : "List<T>:不是参数化类型");
System.out.println(TypeTest.class.getDeclaredField("list3").getGenericType() instanceof ParameterizedType ? "List<?>:是参数化类型" : "List<?>:不是参数化类型");
System.out.println(TypeTest.class.getDeclaredField("list4").getGenericType() instanceof ParameterizedType ? "List<? extends Number>:是参数化类型" : "List<? extends Number>:不是参数化类型");
System.out.println("-----------------------------------------------------------");
ParameterizedType parameterizedType = (ParameterizedType) TypeTest.class.getDeclaredField("map").getGenericType();
for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {
System.out.println("getActualTypeArguments 方法返回值有:" + actualTypeArgument.getTypeName());
}
System.out.println("getRawType 方法返回值:" + parameterizedType.getRawType().getTypeName());
System.out.println("getOwnerType 方法返回值:" + (parameterizedType.getOwnerType() != null ? parameterizedType.getOwnerType().getTypeName() : "null"));
}
}
输出:
Map<Integer,String>:是参数化类型
List<String>:是参数化类型
List<T>:是参数化类型
List<?>:是参数化类型
List<? extends Number>:是参数化类型
-----------------------------------------------------------
getActualTypeArguments 方法返回值有:java.lang.Integer
getActualTypeArguments 方法返回值有:java.lang.String
getRawType 方法返回值:java.util.Map
getOwnerType 方法返回值:null
3. 类型变量(TypeVariable)
类型变量的Type实现类为TypeVariable。
类型变量急速指的泛型符号(不包括通配符)。
源码:
public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
Type[] getBounds();
D getGenericDeclaration();
String getName();
AnnotatedType[] getAnnotatedBounds();
}
方法:
- getBounds:类型变量对应的上边界。如果没有指定上限,返回Object,可以有多个
- getGenericDeclaration:获取类型变量所在类的Type。
- getName:获取类型变量在源码中定义的名称
- getAnnotatedBounds:获取注解类型的上限数组
示例:
public class TypeTest<T> {
private List<T> list2;
private List<?> list3;
private List<? extends Number> list4;
public static void main(String[] args) throws Exception {
System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list2").getGenericType()).getActualTypeArguments()[0] instanceof TypeVariable ? "T:是类型变量" : "T:不是类型变量");
System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list3").getGenericType()).getActualTypeArguments()[0] instanceof TypeVariable ? "?:是类型变量" : "?:不是类型变量");
System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list4").getGenericType()).getActualTypeArguments()[0] instanceof TypeVariable ? "? extends Number:是类型变量" : "? extends Number:不是类型变量");
System.out.println("---------------------------------------------------------------");
TypeVariable typeVariable = (TypeVariable)((ParameterizedType) TypeTest.class.getDeclaredField("list2").getGenericType()).getActualTypeArguments()[0];
for (Type bound : typeVariable.getBounds()) {
System.out.println("getBounds 方法返回值有:" + bound.getTypeName());
}
System.out.println("getGenericDeclaration 方法返回值:" + typeVariable.getGenericDeclaration());
System.out.println("getName 方法返回值:" + typeVariable.getName());
for (AnnotatedType annotatedType : typeVariable.getAnnotatedBounds()) {
System.out.println("getAnnotatedBounds 方法返回值有:" + annotatedType.getType().getTypeName());
}
}
}
输出:
T:是类型变量
?:不是类型变量
? extends Number:不是类型变量
---------------------------------------------------------------
getBounds 方法返回值有:java.lang.Object
getGenericDeclaration 方法返回值:class com.joker.test.generic.TypeTest
getName 方法返回值:T
getAnnotatedBounds 方法返回值有:java.lang.Object
4. 通配符类型(WildcardType)
通配符类型的Type实现类为WildcardType。
源码:
public interface WildcardType extends Type {
Type[] getUpperBounds();
Type[] getLowerBounds();
}
方法:
- getUpperBounds:泛型表达式的上边界(表达式中使用extends)
- getLowerBounds:泛型表达式的下边界(表达式中使用super)
示例:
public class TypeTest<T> {
private List<T> list2;
private List<?> list3;
private List<? extends Number> list4;
private List<? super Number> list5;
public static void main(String[] args) throws Exception {
System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list2").getGenericType()).getActualTypeArguments()[0] instanceof WildcardType ? "T:是通配符类型" : "T:不是通配符类型");
System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list3").getGenericType()).getActualTypeArguments()[0] instanceof WildcardType ? "?:是通配符类型" : "?:不是通配符类型");
System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list4").getGenericType()).getActualTypeArguments()[0] instanceof WildcardType ? "? extends Number:是通配符类型" : "? extends Number:不是通配符类型");
System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list5").getGenericType()).getActualTypeArguments()[0] instanceof WildcardType ? "? super Number:是通配符类型" : "? super Number:不是通配符类型");
System.out.println("-----------------------------------------------");
WildcardType wildcardType1 = (WildcardType)((ParameterizedType) TypeTest.class.getDeclaredField("list4").getGenericType()).getActualTypeArguments()[0];
System.out.println("List<? extends Number> 上边界:"+wildcardType1.getUpperBounds()[0].getTypeName());
WildcardType wildcardType2 = (WildcardType)((ParameterizedType) TypeTest.class.getDeclaredField("list5").getGenericType()).getActualTypeArguments()[0];
System.out.println("List<? super Number> 上边界:"+wildcardType2.getUpperBounds()[0].getTypeName());
System.out.println("List<? super Number> 下边界:"+wildcardType2.getLowerBounds()[0].getTypeName());
}
}
输出:
T:不是通配符类型
?:是通配符类型
? extends Number:是通配符类型
? super Number:是通配符类型
-----------------------------------------------
List<? extends Number> 上边界:java.lang.Number
List<? super Number> 上边界:java.lang.Object
List<? super Number> 下边界:java.lang.Number
5. 泛型数组类型(GenericArrayType)
泛型数组类型的Type实现类为GenericArrayType。
注意:普通类型的数组不属于泛型数组类型(如int[]、Long[]、String[])。
源码:
public interface GenericArrayType extends Type {
Type getGenericComponentType();
}
方法:
- getGenericComponentType:返回泛型数组中成员类型
示例:
public class TypeTest<T> {
private String[] list;
private List<String>[] list1;
private List<T>[] list2;
private List<?>[] list3;
private List<? extends Number>[] list4;
private T[] list5;
public static void main(String[] args) throws Exception {
System.out.println(TypeTest.class.getDeclaredField("list").getGenericType() instanceof GenericArrayType ? "String[]:是泛型数组类型" : "String[]:不是泛型数组类型");
System.out.println(TypeTest.class.getDeclaredField("list1").getGenericType() instanceof GenericArrayType ? "List<String>[]:是泛型数组类型" : "List<String>[]:不是泛型数组类型");
System.out.println(TypeTest.class.getDeclaredField("list2").getGenericType() instanceof GenericArrayType ? "List<T>[]:是泛型数组类型" : "List<T>[]:不是泛型数组类型");
System.out.println(TypeTest.class.getDeclaredField("list3").getGenericType() instanceof GenericArrayType ? "List<?>[]:是泛型数组类型" : "List<?>[]:不是泛型数组类型");
System.out.println(TypeTest.class.getDeclaredField("list4").getGenericType() instanceof GenericArrayType ? "List<? extends Number>[]:是泛型数组类型" : "List<? extends Number>[]:不是泛型数组类型");
System.out.println(TypeTest.class.getDeclaredField("list5").getGenericType() instanceof GenericArrayType ? "T[]:是泛型数组类型" : "T[]:不是泛型数组类型");
System.out.println("------------------------------------------------------");
System.out.println("List<String>[] 数组成员类型:"+((GenericArrayType) TypeTest.class.getDeclaredField("list1").getGenericType()).getGenericComponentType().getTypeName());
System.out.println("List<T>[] 数组成员类型:"+((GenericArrayType) TypeTest.class.getDeclaredField("list2").getGenericType()).getGenericComponentType().getTypeName());
System.out.println("List<?>[] 数组成员类型:"+((GenericArrayType) TypeTest.class.getDeclaredField("list3").getGenericType()).getGenericComponentType().getTypeName());
System.out.println("List<? extends Number>[] 数组成员类型:"+((GenericArrayType) TypeTest.class.getDeclaredField("list4").getGenericType()).getGenericComponentType().getTypeName());
System.out.println("T[] 数组成员类型:"+((GenericArrayType) TypeTest.class.getDeclaredField("list5").getGenericType()).getGenericComponentType().getTypeName());
}
}
输出:
String[]:不是泛型数组类型
List<String>[]:是泛型数组类型
List<T>[]:是泛型数组类型
List<?>[]:是泛型数组类型
List<? extends Number>[]:是泛型数组类型
T[]:是泛型数组类型
------------------------------------------------------
List<String>[] 数组成员类型:java.util.List<java.lang.String>
List<T>[] 数组成员类型:java.util.List<T>
List<?>[] 数组成员类型:java.util.List<?>
List<? extends Number>[] 数组成员类型:java.util.List<? extends java.lang.Number>
T[] 数组成员类型:T