JAVA Type之ParameterizedType 参数化类型

JAVA Type之ParameterizedType 参数化类型

Scroll Down

Java类型之参数化类型 ParameterizedType

源码

public interface ParameterizedType extends Type {
    //1.获得<>中实际类型
    Type[] getActualTypeArguments();
    //2.获得<>前面实际类型
    Type getRawType();
    //3.如果这个类型是某个类型所属,获得这个所有者类型,否则返回null
    Type getOwnerType();
}

概述

ParameterizedType是 JDK7 开始, java.lang.reflect 提供了Interface ParameterizedType. 通过实现这个接口, 我们可以实现泛型类的类型的参数化。

举例:

public class ParameterizedTypeBeanTest {
    public static void main(String[] args) {
        Field[] fields = ParameterizedTypeBean.class.getDeclaredFields();
        for (Field field : fields) {
            Type genericType = field.getGenericType();
            System.out.println(field.getName() + ":" + (genericType instanceof ParameterizedType));
        }
    }
}

class ParameterizedTypeBean {
    //  true
    List<String> listString;
    //  false
    List list;
    //  true
    Map<String, Long> mapString;
    // false
    Map map;
    // true
    Map.Entry<Long, Short> mapLong;
}

打印结果:

listString: true
list: false
mapString: true
map: false
mapLong: true

从打印结果看来,具有<>(泛型)符号的变量是参数化类型。

ParameterizedType方法之getActualTypeArguments

该方法返回一个Type数组
Type[] getActualTypeArguments();

测试代码:

public class ParameterizedTypeBeanTest {
    public static void main(String[] args) {
        // 反射获取字段
        Field[] fields = ParameterizedTypeBean.class.getDeclaredFields();
        for (Field field : fields) {
            if (field.getGenericType() instanceof ParameterizedType) {
                ParameterizedType genericType = (ParameterizedType) field.getGenericType();
                System.out.print("变量类型 = " + genericType.getTypeName() + " ");
                System.out.print("变量名称 = " + genericType.getTypeName() + " ");
                // 泛型类型的数组
                Type[] arguments = genericType.getActualTypeArguments();
                for (Type argument : arguments) {
                    System.out.print("泛型类型 = " + argument.getTypeName() + " ");
                }
                System.out.println();
                System.out.println();
            }
        }
    }
}

class ParameterizedTypeBean {
    //  true
    List<String> listString;
    //  false
    List list;
    //  true
    Map<String, Long> mapString;
    // false
    Map map;
    // true
    Map.Entry<Long, Short> mapLong;
}

打印结果:

变量类型 = java.util.List<java.lang.String>   变量名称 = listString   泛型类型 = java.lang.String   

变量类型 = java.util.Map<java.lang.String, java.lang.Long>   变量名称 = mapString   泛型类型 = java.lang.String   泛型类型 = java.lang.Long   

变量类型 = java.util.Map$Entry<java.lang.Long, java.lang.Short>   变量名称 = mapLong   泛型类型 = java.lang.Long   泛型类型 = java.lang.Short 

从打印结果返回来看,getActualTypeArguments()返回了一个Type数组,数组里是参数化类型的参数。

ParameterizedType方法之getRawType

Type getRawType();
变量的类型

测试代码:

public class ParameterizedTypeBeanTest {
    public static void main(String[] args) {
        // 反射获取字段
        Field[] fields = ParameterizedTypeBean.class.getDeclaredFields();
        for (Field field : fields) {
            if (field.getGenericType() instanceof ParameterizedType) {
                ParameterizedType genericType = (ParameterizedType) field.getGenericType();
                System.out.print("变量类型 = " + genericType.getTypeName() + " ");
                System.out.print("变量名称 = " + genericType.getTypeName() + " ");
                //
                System.out.print("getRawType() = " + genericType.getRawType().getTypeName());
                System.out.println();
                System.out.println();
            }
        }
    }
}

class ParameterizedTypeBean {
    //  true
    List<String> listString;
    //  false
    List list;
    //  true
    Map<String, Long> mapString;
    // false
    Map map;
    // true
    Map.Entry<Long, Short> mapLong;
}

打印结果:

变量类型 = java.util.List<java.lang.String> 变量名称 = java.util.List<java.lang.String> getRawType() = java.util.List

变量类型 = java.util.Map<java.lang.String, java.lang.Long> 变量名称 = java.util.Map<java.lang.String, java.lang.Long> getRawType() = java.util.Map

变量类型 = java.util.Map.java.util.Map$Entry<java.lang.Long, java.lang.Short> 变量名称 = java.util.Map.java.util.Map$Entry<java.lang.Long, java.lang.Short> getRawType() = java.util.Map$Entry

从打印结果来看,getRawType()是变量的类型

ParameterizedType方法之getOwnerType

Type getOwnerType();
对于O<T>.I<S>类型的变量,会返回O<T>

测试代码:

public class ParameterizedTypeBeanTest {
    public static void main(String[] args) {
        // 反射获取字段
        Field[] fields = ParameterizedTypeBean.class.getDeclaredFields();
        for (Field field : fields) {
            if (field.getGenericType() instanceof ParameterizedType) {
                ParameterizedType genericType = (ParameterizedType) field.getGenericType();
                System.out.print("变量名称 = " + genericType.getTypeName() + " ");
                Type ownerType = genericType.getOwnerType();
                if (null != ownerType) {
                    System.out.print("getOwnerType() = " + ownerType.getTypeName());
                } else {
                    System.out.print("getOwnerType() = null");

                }
                System.out.println();
                System.out.println();
            }
        }
    }
}

class ParameterizedTypeBean {
    //  true
    List<String> listString;
    //  false
    List list;
    //  true
    Map<String, Long> mapString;
    // false
    Map map;
    // true
    Map.Entry<Long, Short> mapLong;
}

结果:

变量名称 = java.util.List<java.lang.String> getOwnerType() = null

变量名称 = java.util.Map<java.lang.String, java.lang.Long> getOwnerType() = null

变量名称 = java.util.Map.java.util.Map$Entry<java.lang.Long, java.lang.Short> getOwnerType() = java.util.Map

从打印结果来看,前面两个都为null,最后一个为Map类型

前两个为什么会返回 null 呢。看一下官网的注释:

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

大概意思是说:返回@code type对象,该对象表示此类型所属的类型。例如,如果此类型为@code o<t>.i<s>,则返回@code o<t>的表示形式。
也就是说:

O<T>.I<S>类型的变量,调用getOwnerType()会返回O<T>

官网还有一句:

If this type is a top-level type, {@code null} is returned.
如果此类型是顶级类型,则返回@code null。

总结:

  1. Type 是Java编程语言中所有类型的通用超级接口。这些类型包括原始类型、参数化类型、数组类型、类型变量和基元类型。
    • 内部的 getTypeName() 方法会返回对应类型的全限定类名。
  2. 只有具有<>(泛型)符号的变量是参数化类型。
  3. getActualTypeArguments()返回了一个Type数组,数组里是参数化类型的参数,可以根据这个方法获取到 “泛型的类型”。
  4. getRawType()是获取变量的类型。
  5. getOwnerType()方法对于O<T>.I<S>类型的变量,会返回O<T>,例如:Map.Entry<Long,Short> mapLong,会返回java.util.Map,而不是java.util.Entry。

系列

  1. ParameterizedType 泛型/参数化类型【重要】
  2. TypeVariable 类型变量/泛指任何类【掌握】
  3. GenericArrayType (泛型)数组类型
  4. WildcardType 通配符(泛型)表达式

作者:几行代码
链接:https://www.jianshu.com/p/27772c32fa41
来源:简书