2019-03-15——Java反射 Type
Type 是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型(Class)、参数化类型(ParameterizedType)、数组类型(GenericArrayType)、类型变量(TypeVariable)和基本类型(Class)。它并不是我们平常工作中经常使用的 int、String、List、Map等数据类型,而是从Java语言角度来说,对基本类型、引用类型向上的抽象。
- 原始类型,不仅仅包含我们平常所指的类,还包括枚举、数组、注解等;
- 参数化类型,就是我们平常所用到的泛型List、Map;
- 数组类型,并不是我们工作中所使用的数组String[] 、byte[],而是带有泛型的数组,即T[] ;
- 基本类型,也就是我们所说的java的基本类型,即int,float,double等
Type体系继承结构
反射.pngType是个空接口,没有定义任何方法,通过多态提高了程序的扩展性,具体实现去看下面的子类:
ParameterizedType
参数化类型,即泛型;例如:List<T>、Map<K,V>等带有参数化的对象;
List<String> list1;
List list2;
List<? extends Integer> list3;
Map<Integer,String> map1;
Map map2;
Map<? extends Integer,? super String> map3;
Map.Entry<Long,Short> map4;
比如上面的几个变量的类型,其中list1、list3、map1、map3、map4属于参数化类型。
接口中声明的方法
方法 | 说明 |
---|---|
getActualTypeArguments() | 获取<>中间实际类型 |
getRawType() | 获取<>前面的实际类型 |
getOwnerType() | 如果这个类型是某个类型所属,获取这个所属者的类型,否则返回null |
调用getActualTypeArguments的结果
list1:
java.lang.String
list3:
? extends java.lang.Integer
map1:
java.lang.Integer
java.lang.String
map3:
? extends java.lang.Integer
? super java.lang.String
map4:
java.lang.Long
java.lang.Short
无论<>中有几层嵌套(List<Map<String,Integer>)getActualTypeArguments()方法永远都是脱去最外层的<>(也就是List<>),将口号内的内容(Map<String,Integer>)返回
我们经常遇到的List<T>,通过getActualTypeArguments()方法,得到的返回值是TypeVariableImpl对象,也就是TypeVariable类型
调用getRawType的结果
list1:
java.util.List
list3:
java.util.List
map1:
java.util.Map
map3:
java.util.Map
map4:
java.util.Map$Entry
调用getOwnerType的结果
list1:
null
list3:
null
map1:
null
map3:
null
map4:
java.util.Map
GenericArrayType
泛型数组类型,用来描述ParameterizedType、TypeVariable类型的数组;即List<T>[] 、T[]等;
方法 | 说明 |
---|---|
getGenericComponentType() | 获得这个数组元素类型,即获得T[] |
TypeVariable
类型变量,即泛型中的变量;例如:T、K、V等变量,可以表示任何类;
在这需要强调的是,TypeVariable代表着泛型中的变量,而ParameterizedType则代表整个泛型;
方法 | 说明 |
---|---|
getBounds() | 获取泛型的上界,无显示定义为Object |
getGenericDeclaration() | 获取声明该类型变量的实体,即获得类、方法或构造器名 |
getName() | 获取名称,即K、V、R之类的 |
需要注意的是因为泛型中的类型变量只能声明在类、方法和构造器上,所以getGenericDeclaration方法返回的也只有类、方法或构造器名。
调用getBounds的结果
public class Fruit<T extends String> {
public static void main(String[] args) {
TypeVariable<Class<Fruit>>[] variables = Fruit.class.getTypeParameters();
for (TypeVariable<Class<Fruit>> variable : variables) {
System.out.println(variable.getTypeName());
Type[] bounds = variable.getBounds();
for (Type bound : bounds) {
System.out.println(bound.getTypeName());
}
}
}
}
T
java.lang.String
调用getGenericDeclaration的结果
public class Fruit<T extends String> {
public static void main(String[] args) {
TypeVariable<Class<Fruit>>[] variables = Fruit.class.getTypeParameters();
for (TypeVariable<Class<Fruit>> variable : variables) {
System.out.println(variable.getTypeName());
Class<Fruit> declaration = variable.getGenericDeclaration();
System.out.println(declaration.getName());
}
}
}
T
practice.Fruit
调用getName的结果
public class Fruit<T extends String> {
public static void main(String[] args) {
TypeVariable<Class<Fruit>>[] variables = Fruit.class.getTypeParameters();
for (TypeVariable<Class<Fruit>> variable : variables) {
System.out.println(variable.getTypeName());
String name = variable.getName();
System.out.println(name);
}
}
}
T
T
Class
上三者不同,Class是Type的一个实现类,属于原始类型,是Java反射的基础,对Java类的抽象;在程序运行期间,每一个类都对应一个Class对象,这个对象包含了类的修饰符、方法,属性、构造等信息,所以我们可以对这个Class对象进行相应的操作,这就是Java的反射。
WildcardType
泛型表达式(或者通配符表达式),即? extend Number、? super Integer这样的表达式;WildcardType虽然是Type的子接口,但却不是Java类型中的一种;