java 反射学习笔记(三)—— Type接口

[TOC]


Type接口.png

概述

Type是Java语言中所有类型的公共高级接口。

这个所有类型是从Java语言角度来说的,如上图可见(Class类也实现了该接口),Type体系包括了Class、参数化类型(ParameterizedType)、数组类型(GenericArrayType)、类型变量(TypeVariable)。

Type的使用

1.Class

type有一个实现类和4个实现接口,当需要描述的类型是:普通的类,自定义的类,也就是和 泛型无关的类 ,java可以直接将这个type类强转为Class。

2. TypeVariable

TypeVariable 是类型变量的常用超级接口。类型变量在反射方法首次需要时创建。指的是List中的T,实际的Java类型是TypeVariableImpl。也可以对类型变量加上extend限定,这样会有类型变量对应的上限。

获取一个对象的泛型声明方式通常是通过class类,class类实现了GenericDecalaration接口,该接口只有一个方法,返回的是代表了泛型声明的泛型变量数组。

public interface GenericDeclaration extends AnnotatedElement {
  
    public TypeVariable[] getTypeParameters();
}
TypeVariable>[] typeVariables = user.getClass().getTypeParameters();
        for (TypeVariable> typeVariable :typeVariables){
            System.out.println(typeVariable.getName()); //输出T
            Stream.of(typeVariable.getBounds()).forEach(System.out::println); //没有上限默认输出Object
            System.out.println(typeVariable.getGenericDeclaration()); // 输出user,因为是在user类上声明的泛型
        }

public interface TypeVariable extends Type, AnnotatedElement {
    /**
    *返回表示此类型变量上边界的Type对象数组
    */
    Type[] getBounds();

    /**
     * Returns the {@code GenericDeclaration} object representing the
     * generic declaration declared this type variable.
     *
     * @return the generic declaration declared for this type variable.
     *
     * @since 1.5
     */
    D getGenericDeclaration();

    /**
     * Returns the name of this type variable, as it occurs in the source code.
     *
     * @return the name of this type variable, as it appears in the source code
     */
    String getName();

}

3. ParameterizedType

表示一个参数化类型,也就是泛型,例如List,该接口内主要有3个方法

/**
 * ParameterizedType represents a parameterized type such as
 * Collection<String>.
 */
public interface ParameterizedType extends Type {
    /**
     * Returns an array of {@code Type} objects representing the actual type
     * arguments to this type.
     * 获取泛型中的实际类型
     */
    Type[] getActualTypeArguments();

    /**
     * Returns the {@code Type} object representing the class or interface
     * that declared this type.
     * 
     * @return the {@code Type} object representing the class or interface
     *     that declared this type
     * 获取声明泛型的类或者接口,也就是泛型中<>前面的那个值。
     */
    Type getRawType();

    /**
     * Returns a {@code Type} object representing the type that this type
     * is a member of.  For example, if this type is {@code O.I},
     * return a representation of {@code O}.
     *
     * 

If this type is a top-level type, {@code null} is returned. * * @return a {@code Type} object representing the type that * this type is a member of. If this type is a top-level type, * 获取泛型的拥有者 */ Type getOwnerType(); }

通常,我们可以使用该接口来检验泛型是否被参数化。通过instance判断是已经参数化了之后,再通过getactualTypeArguments方法获取参数化类型。具体可参考下面的代码。

如何获取参数化类型

这里说的参数化类型指的就是泛型的实际形式,即将类型以参数的方式进行传递。这里需要注意的点是Java是共享泛型模式,子类的泛型标识在编译时就会被擦除,不会写入到实际子类型中,所以无法得到自身标识的类型参数。要想得到泛型信息,只能从上层类型中得到(可以是继承的父类或者实现的接口)。从下面的代码中也能看出,调用Son.getclass方法能够获得类型参数class.User,而调用Fathor的该方法时却会报错。从代码也能看出,我们得到的参数类型也不是通过构造方法传入的类型,而是从父类传递下来的参数类型。

public class Fathor {
    public void getClazz(){
        Type type = this.getClass().getGenericSuperclass();
        System.out.println(type);
        Type[] types = ((ParameterizedType)type).getActualTypeArguments();
        Stream.of(types).forEach(System.out::println);
    }
}
public class Son extends Fathor {
    @Override
    public void getClazz() {
        Type type = this.getClass().getGenericSuperclass();
        System.out.println(type);
        if(type instanceof ParameterizedType) {
            Type[] types = ((ParameterizedType)type).getActualTypeArguments();
            Stream.of(types).forEach(System.out::println);
        }
    }
}
public static void main(String[] args) {
        new Son().getClazz();
        new Fathor().getClazz();
    }
//输出
instance.Fathor
class instance.User
class java.lang.Object
Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
    at instance.Fathor.getClazz(Fathor.java:15)
    at wytest.Test2.main(Test2.java:15)

4. GenericArrayType

泛型数组类型,例如List[]

public interface GenericArrayType extends Type {
    //返回泛型数组中元素的Type类型,
    Type getGenericComponentType();
}

你可能感兴趣的:(java 反射学习笔记(三)—— Type接口)