java type设计分析

java的Type设计分析

1.5版本后,java设计了Type,但是对于Type是什么一直也是和清晰,所以一起看一下吧。分析的方式采用UML类图的方式,进行功能设计的解释说明。

设计分析

在这里插入图片描述

  1. Type接口

    这个接口是所有类型的超类,只有一个没有很大作用的getTypeName()的默认方法,默认返回toString。

  2. GenericArrayType接口

    是一个数组类型接口,它的元素是ParameterizedType或者TypeVariable。只有一个方法,返回数组元素的类型。
    举例:

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        List<List<String>> strList = new ArrayList<>();
        String[] strArr = new String[]{};
        // cannot create generic array type but can use field or method get generic type
        List<String>[] listArr = new List[1];
        listArr[0] = Lists.newArrayList("11");
        System.out.println("list===>" + isGenericArrayType(list.getClass().getGenericInterfaces()));
        System.out.println("strList===>" + isGenericArrayType(strList.getClass().getGenericInterfaces()));
        System.out.println("str==>" + isGenericArrayType(strArr.getClass().getGenericInterfaces()));
        System.out.println("listArr==>" + isGenericArrayType(listArr.getClass().getGenericInterfaces()));
    
        Method method = GenericArrayTypeBean.class.getDeclaredMethods()[0];
        System.out.println(method);
        // public void test(List<String>[] pTypeArray, T[]
        // vTypeArray,List<String> list, String[] strings, Person[] ints)
        Type[] types = method.getGenericParameterTypes(); // 这是 Method 中的方法
        for (Type type : types) {
            System.out.println(type instanceof GenericArrayType);// 依次输出true,true,false,false,false
        }
    
        }
    
        private static boolean isGenericArrayType(Type[] types) {
             return Stream.of(types).anyMatch(type -> type instanceof GenericArrayType);
       }
    
        public class GenericArrayTypeBean<T> {
    
        public void test(List<String>[] pTypeArray, T[] vTypeArray,
                         List<String> list, String[] strings) {
        }
    }
    
    list===>false
    strList===>false
    str==>false
    listArr==>false
    public void com.jd.xstore.stock.center.biz.stock.schedule.JdBuyStockNumChangeSchedule$GenericArrayTypeBean.test(java.util.List[],java.lang.Object[],java.util.List,java.lang.String[])
    true
    true
    false
    false
    
  3. WilcardType

    通配符的类型,经常的用法是?,? extends,? super等。有两个方法, getUpperBoundsgetLowerBounds

    • Type[] getUpperBounds()返回的是一个上限类型数组。如果没有声明,那么上限是Object
    • Type[] getLowerBounds()返回是一个下限类型数组。没有声明,返回长度为0的数组。
    public static void main(String[] args) {
        List<? extends String> list = new ArrayList<>();
        isWildcardType(list.getClass().getGenericInterfaces());
    
        Field[] declaredFields = GenericBean.class.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(field -> {
            Type genericType = field.getGenericType();
            if (genericType instanceof ParameterizedType) {
                Arrays.stream(((ParameterizedType) genericType).getActualTypeArguments()).forEach(type ->
                        System.out.println(type.getTypeName() + ": " + (type instanceof WildcardType)));
            }
            System.out.println(field.getName() + ": " + (genericType instanceof WildcardType));
        });
        }
    
        private static void isWildcardType(Type[] types) {
            for (Type type : types) {
               if (type instanceof ParameterizedType) {
                   Type actualTypeArgument = ((Parameterize    dType) type).getActualTypeArguments()[0];
                    System.out.println(actualTypeArgument.getTypeName() + ": " + (actualTypeArgument instanceof WildcardType));
               }
           }
        }
    
        public class GenericBean {
            private List<? extends String> list;
            private List<String> strList;
        }
    
    E: false
    ? extends java.lang.String: true
    list: false
    java.lang.String: false
    strList: false
    this$0: false
    
  4. ParameterizedType

    这个是比较常见的类型,但是并没说指定的很明白。个人理解是如果Class可以接受可变类型,这里以T来表示,Class<T>这种就是参数泛型。

    • Type[] getActualTypeArguments()获取T的真正类型,
    • Type getRawType() 返回Class类型。比如List<String>返回java.util.List

    这个示例就略了。上述都有判断ParameterizedType的。

  5. TypeVariable
    这个官方给的解释很多,我们这里可以理解Class和方法中的T,V就是TypeVariable。个人觉得可以理解为类型用来标志泛型的变量,可以有上下限

    public static void main(String[] args) {
        List<? extends String> list = new ArrayList<>();
        isTypeVariable(list.getClass().getGenericInterfaces());
    
        Field[] declaredFields = GenericBean.class.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(field -> {
            Type genericType = field.getGenericType();
            if (genericType instanceof ParameterizedType) {
                Arrays.stream(((ParameterizedType) genericType).getActualTypeArguments()).forEach(type ->
                        System.out.println(type.getTypeName() + ": " + (type instanceof TypeVariable)));
            }
            System.out.println(field.getName() + ": " + (genericType instanceof TypeVariable));
        });
    
        Method[] methods = GenericBean.class.getMethods();
        Arrays.stream(methods).forEach(m -> {
            Type[] genericParameterTypes = m.getGenericParameterTypes();
            Arrays.stream(genericParameterTypes).forEach(type -> System.out.println(m.getName() + ":" + type.getTypeName() + (type instanceof TypeVariable)));
        });
    }
    
    private static void isTypeVariable(Type[] types) {
        for (Type type : types) {
            if (type instanceof ParameterizedType) {
                Type actualTypeArgument = ((ParameterizedType) type).getActualTypeArguments()[0];
                System.out.println(actualTypeArgument.getTypeName() + ": " + (actualTypeArgument instanceof TypeVariable));
            }
        }
    }
    
    public class GenericBean<T> {
        private List<? extends String> list;
        private List<String> strList;
    
        public void test(T t) {
        }
    
        public <V> void test2(V v) {
    
        }
    }
    
    E: true
    ? extends java.lang.String: false
    list: false
    java.lang.String: false
    strList: false
    this$0: false
    test:Ttrue
    test2:Vtrue
    
  6. GenericDeclaration
    A common interface for all entities that declare type variables.
    GenericDeclaration接口继承了AnnotatedElement接口,是所有“可以声明(定义)范型变量”的实体的公共接口。也就是说只有实现了这个接口的才能在对应“实体”上声明TypeVariable。目前实现实体有Class, Method, Constructor.

    • 只有一个方法getTypeParameters获取TypeVariable<?>[]

    例子:

     public static void main(String[] args) {
         Map<String, Integer> map = new HashMap<>();
         System.out.println(Arrays.toString(((GenericDeclaration) map.getClass()).getTypeParameters()));
     }
     [K, V]
    

Type类型还是很抽象的,还是以后继续了解。资料也不很多。
在梳理的过程中,发现了以下的问题:

Type类型如何获取?
GenericDeclaration是通过获取Class,Method,Constructor的class进行获取的。
GenericArrayType不能直接实例化,只能通过method或者field的genericType进行获取
WildcardType同GenericArrayType
ParameterizedType 是Collection<E>实现类,实现类的getClass的type就可以。也可以实例化,但是实例化后获取不到对应的泛型,只能获取到泛型变量
TypeVariable 这个是class中才可以获取到的。

为什么List<String>会instanceof ParameterizedType 如何实现的?
待填坑

最后说一句,因为要兼容的原因,Type在运行时会被擦除。就先到这里,各位晚安

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值