Java泛型中的Type体系

今天看一个开源库源码的时候,发现里面针对泛型Type做了很多处理,我这块不怎么了解,故此研究一下。

关于java.lang.reflect.Type的分类先说明一下,Type作为一个接口,下面有4个继承它的子接口,分别是TypeVariableParameterizedTypeWildcardTypeGenericArrayType。这里我就不给专业名词了,之前我看很多文章,给的专业名词,到最后我也没能区分清楚,这里就直接上例子,通过例子来说明。

  • TypeVariable

    这个怎么说,看字面翻译的意思是类型变量,我个人理解呢,它其实相当于在方法声明当中的形参。也就是你声明时写的是啥,获取到的就是啥。

    public class GenericType {
    
        public static void main(String[] args) {
            ChildCls childCls = new ChildCls();
        }
    }
    
    class SuperCls {
    
        public SuperCls() {
            TypeVariable[] typeParameters = getClass().getSuperclass().getTypeParameters();// [K,V]
            for (TypeVariable typeVariable : typeParameters) {
                p("getSuperclass().getTypeParameters()=" + typeVariable);// 这里分别输出K,V
                Type[] bounds = typeVariable.getBounds();
                for (Type type : bounds) {
                    p(type);// 分别输出class java.lang.Object
                }
            }
        }
        void p(Object obj) {
            System.out.println(obj.toString());
        }
    }
    
    class ChildCls extends SuperClssuper String>, Integer> {}
  • ParameterizedType

    这个,字面意思,参数化的类型。个人理解相当于你调用方法(声明的泛型类),并传入一些参数(泛型类型)。还是上面的例子。

    class SuperCls {
    
    public SuperCls() {
        Type genericSuperclass = getClass().getGenericSuperclass();
        p("getGenericSuperclass()=" + genericSuperclass);
            //test.SuperCls, java.lang.Integer>  注意这个输出,它是一个ParameterizedType类型的,这里理解为调用另一个方法。
        p(genericSuperclass instanceof ParameterizedType);// true
        p(genericSuperclass instanceof WildcardType);// false
        p(genericSuperclass instanceof GenericArrayType);// false
        p(genericSuperclass instanceof TypeVariable);// false
    
            // getActualTypeArguments() 这个方法,个人理解,就是去掉当前ParameterizedType类型最外层的<>后获得的结果。
        Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass)
                .getActualTypeArguments();
        p(actualTypeArguments[0]);// test.SuperCls   注意了,这个仍然是ParameterizedType类型的,因为它还在调用,还包含有<>。
        // 所以可以这么理解,带<>的都是ParameterizedType类型的。
        p(actualTypeArguments[0] instanceof ParameterizedType);// true
        p(actualTypeArguments[0] instanceof WildcardType);// false
        p(actualTypeArguments[0] instanceof GenericArrayType);// false
        p(actualTypeArguments[0] instanceof TypeVariable);// false
        p(actualTypeArguments[1]);// class java.lang.Integer 这个就相当于实参吧。它不属于这4种中的任何一种类型。而我们平时获取泛型类型的方式就是如此。
        p(actualTypeArguments[1] instanceof ParameterizedType);// false
        p(actualTypeArguments[1] instanceof WildcardType);// false
        p(actualTypeArguments[1] instanceof GenericArrayType);// false
        p(actualTypeArguments[1] instanceof TypeVariable);// false
    
    }
    }
  • WildcardType

    这个,是带通配符的泛型,这种类型是可以获取上下边界的,需要注意的是,? extends String(这里的String可以是别的任何对象) ,这种情况下,是没有下边界的。

    class SuperCls {
    
    public SuperCls() {
        Type genericSuperclass = getClass().getGenericSuperclass();
        p("getGenericSuperclass()=" + genericSuperclass);
        // test.SuperCls, java.lang.Integer> 注意这个输出
    
        Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass)
                .getActualTypeArguments();
        p(actualTypeArguments[0]);// test.SuperCls 注意了,这个就是ParameterizedType类型的。这里理解为调用另一个方法
        Type[] actualTypeArguments1 = ((ParameterizedType) actualTypeArguments[0]).getActualTypeArguments();// 再次去掉最外层的<>
        p(actualTypeArguments1[0]);// ? extends java.lang.String      
        p(actualTypeArguments1[0] instanceof ParameterizedType);// false
        p(actualTypeArguments1[0] instanceof WildcardType);// true
        p(actualTypeArguments1[0] instanceof GenericArrayType);// false
        p(actualTypeArguments1[0] instanceof TypeVariable);// false
        Type[] lowerBounds = ((WildcardType) actualTypeArguments1[0]).getLowerBounds();
        p("lowerBounds.length=" + lowerBounds.length);// 0
        for (Type type : lowerBounds) {
            p(type);// 无输出,长度为0
        }
        Type[] upperBounds = ((WildcardType) actualTypeArguments1[0]).getUpperBounds();
        p("upperBounds.length=" + upperBounds.length);// 1
        for (Type type : upperBounds) {
            p(type);// class java.lang.String
        }
    
        p(actualTypeArguments1[1]);// ? super java.lang.String
        p(actualTypeArguments1[1] instanceof ParameterizedType);// false
        p(actualTypeArguments1[1] instanceof WildcardType);// true
        p(actualTypeArguments1[1] instanceof GenericArrayType);// false
        p(actualTypeArguments1[1] instanceof TypeVariable);// false
        Type[] lowerBounds1 = ((WildcardType) actualTypeArguments1[1]).getLowerBounds();
        p("lowerBounds1.length=" + lowerBounds1.length);// 1
        for (Type type : lowerBounds1) {
            p(type);// class java.lang.String
        }
        Type[] upperBounds1 = ((WildcardType) actualTypeArguments1[1]).getUpperBounds();
        p("upperBounds1.length=" + upperBounds1.length);// 1
        for (Type type : upperBounds1) {
            p(type);// class java.lang.Object
        }
    
    }
    }
  • GenericArrayType

    这个是数组类型的泛型。顾名思义,就是传入的泛型类型是个泛型数组。这个例子和上面的有点区别。

    需要注意的是:如果传入的是String[]或者别的一些对象数组,则获取到的不是这4种中的任意一种,必须传入泛型数组。

    public class GenericType {
    
    public static void main(String[] args) {
        ChildCls childCls = new ChildCls();
    }
    }
    
    class SuperCls {
    
    public SuperCls() {
        Type genericSuperclass = getClass().getGenericSuperclass();
        p(genericSuperclass);
    
        Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass)
                .getActualTypeArguments();
        p(actualTypeArguments[0]);// K[]
        p(actualTypeArguments[0] instanceof ParameterizedType);// false
        p(actualTypeArguments[0] instanceof WildcardType);// false
        p(actualTypeArguments[0] instanceof GenericArrayType);// true
        p(actualTypeArguments[0] instanceof TypeVariable);// false
    
        p(actualTypeArguments[1]);// V[]
        p(actualTypeArguments[1] instanceof ParameterizedType);// false
        p(actualTypeArguments[1] instanceof WildcardType);// false
        p(actualTypeArguments[1] instanceof GenericArrayType);// true
        p(actualTypeArguments[1] instanceof TypeVariable);// false
    
    }
    
    void p(Object obj) {
        System.out.println(obj.toString());
    }
    }
    
    class ChildCls extends SuperCls {
    }

ok,大致就是这样,这些东西主要是自己的一些理解看法,一些说法上可能并不正确,如果错误,请评论指出~

也欢迎大家留言交流!

你可能感兴趣的:(Java,java,泛型)