技术栈

2019-03-15——Java反射 Type

2019-03-19  本文已影响0人  烟雨乱平生

Type 是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型(Class)、参数化类型(ParameterizedType)、数组类型(GenericArrayType)、类型变量(TypeVariable)和基本类型(Class)。它并不是我们平常工作中经常使用的 int、String、List、Map等数据类型,而是从Java语言角度来说,对基本类型、引用类型向上的抽象。

Type体系继承结构

反射.png

Type是个空接口,没有定义任何方法,通过多态提高了程序的扩展性,具体实现去看下面的子类:

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类型中的一种;

上一篇 下一篇

猜你喜欢

热点阅读