Type 接口

Type 接口

讨论版本为 JDK1.8

java.lang.reflect.Type,所有类型的父接口,在 JDK1.5 引入,接口的源码如下

public interface Type {
    /**
     * Returns a string describing this type, including information
     * about any type parameters.
     *
     * @implSpec The default implementation calls {@code toString}.
     *
     * @return a string describing this type
     * @since 1.8
     */
    default String getTypeName() {
        return toString();
    }
}

其实继承关系如下

继承关系

其中有四个子接口和一个实现类

  • Type
    • GenericArrayType 泛型数组
    • ParameterizedType 参数化类型
    • WildcardType 泛型表达式
    • TypeVariable 类型变量
    • Class 普通类

GenericArrayType

定义

类似 T[] 或者 List<T>[] 等,描述的是 ParameterizedType 类型以及 TypeVariable 类型数组

源码

public interface GenericArrayType extends Type {
 	// 返回去掉最右边数组后的类型
    Type getGenericComponentType();
}

例子

public class GenericArrayTypeTest {
    public static void main(String[] args) throws NoSuchFieldException {
        GenericArrayType type = (GenericArrayType)GenericArrayTypeBean.class.getDeclaredField("data").getGenericType();
        System.out.println(type.getTypeName());
        System.out.println(type.getGenericComponentType());
    }
}

class GenericArrayTypeBean<T> {
    List<T>[][] data;
}

// 输出结果
// java.util.List<T>[][]
// java.util.List<T>[]

ParameterizedType

定义

参数化类型,类似 Map<T, K>,即常说的泛型

源码

public interface ParameterizedType extends Type {
    // 获取所有的泛型,因为有两个或以上的泛型,所以返回值为数组,只获取第一层 <> 内的内容
    Type[] getActualTypeArguments();
	// 获取参数 <> 外的类型
    Type getRawType();
	// 获取参数类型所属的类,即是哪个类的内部类,如果没有,就返回 null
    Type getOwnerType();
}

例子

public class ParameterizedTypeTest {
    public static void main(String[] args) throws NoSuchMethodException {
        // 获取方法的参数类型
        Type[] types = ParameterizedTypeBean.class.getMethod("parameterizedTypeTest", Map.Entry.class).getGenericParameterTypes();
        ParameterizedType type = (ParameterizedType) types[0];
        System.out.println(type.getTypeName());
        System.out.println(type.getActualTypeArguments()[0]);
        System.out.println(type.getActualTypeArguments()[1]);
        System.out.println(type.getRawType());
        System.out.println(type.getOwnerType());
    }
}

class ParameterizedTypeBean<T, K> {
    public void parameterizedTypeTest(Map.Entry<T, List<K>> data) {
        return;
    }
}

// 输出结果
// java.util.Map$Entry<T, java.util.List<K>>
// T
// java.util.List<K>
// interface java.util.Map$Entry
// interface java.util.Map

WildcardType

定义

返回类型的表达式,例如 ?? extends Number 等,根据 java doc 所言,返回值虽然为数组,只是为了以后扩展用的,现在只会返回一个

源码

public interface WildcardType extends Type {
	// 获取上限
    Type[] getUpperBounds();
	// 获取下限
    Type[] getLowerBounds();
    // one or many? Up to language spec; currently only one, but this API
    // allows for generalization.
}

例子

public class WildcardTypeTest {
    public static void main(String[] args) throws NoSuchMethodException {
        ParameterizedType parameterizedType = (ParameterizedType)WildcardTypeBean.class.getMethod("wildcardTypeTest", Map.class).getGenericReturnType();
        for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {
            WildcardType type = (WildcardType) actualTypeArgument;
            System.out.println(type.getTypeName());
            System.out.println(type.getUpperBounds()[0]);
        }
    }
}

class WildcardTypeBean<T, K> {
    public List<? extends Number> wildcardTypeTest(Map<T, K> map) {
        return null;
    }
}

// 输出结果
// ? extends java.lang.Number
// class java.lang.Number

TypeVariable

定义

在类或者方法上定义类型变量,可以看到也有一个泛型参数,要求需要是 GenericDeclaration 的子类,其继承关系如下

GenericDeclaration

  • Class
  • Executable
    • Method
    • Constructor

所以我们只能在类型,例如 Class,Interface、方法和构造函数这三个地方声明泛型参数

源码

public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
	// 获得该类型变量的上限,若无显式定义,默认为 Object
    Type[] getBounds();
	// 获得定义这个类型参数的类
    D getGenericDeclaration();
	// 获得这个类型变量在定义时候的名称
    String getName();

    // since1.8 如果这个这个泛型参数类型的上界用注解标记了,可以通过它拿到相应的注解
    AnnotatedType[] getAnnotatedBounds();
}

例子

public class TypeVariableTest {
    public static void main(String[] args) throws NoSuchMethodException {
        TypeVariable<Class<TypeVariableBean>>[] typeParameters = TypeVariableBean.class.getTypeParameters();
        for (TypeVariable<Class<TypeVariableBean>> typeParameter : typeParameters) {
            System.out.println(typeParameter.getTypeName());
            System.out.println(typeParameter.getGenericDeclaration());
            for (AnnotatedType annotatedBound : typeParameter.getAnnotatedBounds()) {
                for (Annotation annotation : annotatedBound.getAnnotations()) {
                    System.out.println(annotation);
                }
            }
            for (Type bound : typeParameter.getBounds()) {
                System.out.println(bound.getTypeName());
            }
            System.out.println("-------------------------------------");
        }
    }
}

class TypeVariableBean<T extends @CustomAnnotation Number & Comparable<T>, K> {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface CustomAnnotation {
}

// 输出结果
// T
// class com.yczuoxin.demo.TypeVariableBean
// @com.yczuoxin.demo.CustomAnnotation()
// java.lang.Number
// java.lang.Comparable<T>
// -------------------------------------
// K
// class com.yczuoxin.demo.TypeVariableBean
// java.lang.Object
// java.lang.Object
-------------------------------------
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值