Java泛型中的Type体系

来源:互联网 发布:竞拍网站源码 编辑:程序博客网 时间:2024/05/07 11:55

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

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

  • TypeVariable

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

    public class GenericType {    public static void main(String[] args) {        ChildCls childCls = new ChildCls();    }}class SuperCls<K, V> {    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 SuperCls<SuperCls<? extends String, ? super String>, Integer> {}
  • ParameterizedType

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

    class SuperCls<K, V> {public SuperCls() {    Type genericSuperclass = getClass().getGenericSuperclass();    p("getGenericSuperclass()=" + genericSuperclass);        //test.SuperCls<test.SuperCls<? extends java.lang.String, ? super java.lang.String>, 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<? extends java.lang.String, ? super java.lang.String>   注意了,这个仍然是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<K, V> {public SuperCls() {    Type genericSuperclass = getClass().getGenericSuperclass();    p("getGenericSuperclass()=" + genericSuperclass);    // test.SuperCls<test.SuperCls<? extends java.lang.String, ? super java.lang.String>, java.lang.Integer> 注意这个输出    Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass)            .getActualTypeArguments();    p(actualTypeArguments[0]);// test.SuperCls<? extends java.lang.String, ? super java.lang.String> 注意了,这个就是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<K, V> {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<K, V> extends SuperCls<K[], V[]> {}

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

也欢迎大家留言交流!

0 0
原创粉丝点击