打开java api 文档可以Type是一个空接口
Type 是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。讲的就是他的几个直接子类
大概意思就是:Type是所有类型的公共接口(父接口),其意义表示Java所有类型,这里所谓的类型是从Java整个语言角度来看的,比如原始类型、参数化类型(泛型)、类型变量及其数组等。
Type跟class的区别:这里Class是Type的一种类型,而像数组、枚举等“类型”是相对于Class来说。
所有已知子接口:GenericArrayType, ParameterizedType, TypeVariable, WildcardType
参数化类型,即泛型,类似List、Map
public interface ParameterizedType extends Type {
//1.获得<>中实际类型
Type[] getActualTypeArguments();
//2.获得<>前面实际类型
Type getRawType();
//3.如果这个类型是某个类型所属,获得这个所有者类型,否则返回null
Type getOwnerType();
}
分别举例说明:
获得参数化类型中<>里的类型参数的类型,因为可能有多个类型参数,例如Map
1. List<ArrayList> a1;//这里返回的是,ArrayList,Class类型
2. List<ArrayList<String>> a2;//这里返回的是ArrayList<String>,ParameterizedType类型
3. List<T> a3;//返回的是T,TypeVariable类型
4. List<? extends Number> a4; //返回的是WildcardType类型
5. <泛型数组,描述的是形如:A<T>[]或T[]类型。> a5;//GenericArrayType
返回最外层<>前面那个类型,即Map
Method method = new Demo().getClass().getMethod("method",Map.Entry.class);
Type[] types = method.getGenericParameterTypes();
ParameterizedType pType = (ParameterizedType)types[0];
//返回所有者类型
System.out.println(getRawType());
//打印结果是interface java.util.Map
}
class Demo{
public static <K,V> void method(Map<K,V> mapEntry){}
}
获得这个类型的所有者的类型
Method method = new Demo().getClass().getMethod("method",Map.Entry.class);
Type[] types = method.getGenericParameterTypes();
ParameterizedType pType = (ParameterizedType)types[0];
//返回所有者类型
System.out.println(pType.getOwnerType());
//打印结果是interface java.util.Map
}
class Demo{
public static <T,U> void method(Map.Entry<T,U> mapEntry){}
}
类型变量,如参数化类型中的E、K等类型变量,表示泛指任何类,如果加上extends/super限定,则就会有相应的上限、下限。
源码:
public interface TypeVariable<D extends GenericDeclaration> extends Type {
//获得泛型的上限,若未明确声明上边界则默认为Object
Type[] getBounds();
//获取声明该类型变量实体(即获得类、方法或构造器名)
D getGenericDeclaration();
//获得名称,即K、V、E之类名称
String getName();
}
获得声明(定义)这个类型变量的类型及名称
Constructor constructor=Demo.getClass().getConstructor(String.class);
TypeVariable typeVariable = constructor.getTypeParameters()[0];
System.out.println(typeVariable.getGenericDeclaration());
//打印出com.xxx.xxx.Demo()
class Demo<T>{
public Demo(T name){}
获得该类型变量的上限(上边界),若无显式定义(extends),默认为Object,类型变量的上限可能不止一个,因为可以用&符号限定多个(这其中有且只能有一个为类或抽象类,且必须放在extends后的第一个,即若有多个上边界,则第一个&后必为接口)
class A<K extends classA & interfaceB, V>{
K key;
V value;
}
Type[] types = A.class.getTypeParameters();
for(Type type : types){
TypeVariable t = (TypeVariable)type;
System.out.println(t.getGenericDeclaration());
int size = t.getBounds().length;
System.out.println(t.getBounds()[size - 1]);
System.out.println(t.getName() + "\n-------------分割线-------------");
}
//输出结果
class com.xxx.xxx.A
interface com.fcc.test.interfaceB
K
-------------分割线-------------
class com.xxx.xxx.A
class java.lang.Object
V
-------------分割线-------------
获得这个类型变量在声明(定义)时候的名称
Constructor constructor=Demo.getClass().getConstructor(String.class);
TypeVariable typeVariable = constructor.getTypeParameters()[0];
String name=typeVariable.getName();
//打印出name="name";
class Demo<T>{
public Demo(T name){}
泛型数组,表示上面两种的数组类型,即形如:A[],T[][]类型。
源码:
public interface GenericArrayType extends Type {
//获得这个数组元素类型,即获得:A<T>(A<T>[])或T(T[])
Type getGenericComponentType();
}
GenericArrayType,泛型数组,描述的是ParameterizedType类型以及TypeVariable类型数组,即形如:classA[][]、T[]等,是Type的子接口。
classA<K>[][] key;
Type type = Demo.class.getDeclaredField("key").getGenericType(); System.out.println(((GenericArrayType)type).getGenericComponentType());
//输出结果
//com.xxx.xxx.classA<K>[]
通配符表达式,或泛型表达式,它虽然是Type的一个子接口,但并不是Java类型中的一种,表示的仅仅是类似 ? extends T、? super K这样的通配符表达式。
源码:
public interface WildcardType extends Type {
//获得泛型表达式上界(上限)
Type[] getUpperBounds();
//获得泛型表达式下界(下限)
Type[] getLowerBounds();
}
class Demo{
public void test(List<? extends Number> a, List<? super Number> b) {
}
Method method=Demo.getClass.getMethod("test",List.class,List.class);
Type[] types = method.getGenericParameterTypes();
for(Type type : types){
Type[] actualTypeArgument =
((ParameterizedType)type).getActualTypeArguments();
for(Type t : actualTypeArgument){
WildcardType wildcardType =
(WildcardType) t;
lowerBounds =wildcardType.getLowerBounds();
upperBounds = wildcardType.getUpperBounds();
}
}
}
输出结果:
[class java.lang.Number]
看明白这些你就可以随心所欲的解析你的泛型,特别是在自己的网络请求中使用Gosn或者FastJson解析带有泛型对象
//一般的服务器都会返回这样的数据格式
class Result<T>{
private int code;
private String msg;
private T data
}
//根据你的实际需求获取对应的type,就可以得到泛型
T data = gson.fromJson(jsonString, type);