Java Type 体系简单认知

2020-12-28  本文已影响0人  summerlines
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 *反射之 泛型 Type 体系认知:ParameterizedType , GenericArrayType , TypeVariable , WildcardType  + Class 也属于Type(唯一直接子类impl而非 extends 的interface类)
 * 构成了java里的所有Type类别体系
 */
public class Test<T,K,V> {

    /**
     * 0 位置Type : className -> class sun.reflect.generics.reflectiveObjects.TypeVariableImplimpl interfaceName -> TypeVariable
     * 1 位置Type : className -> class sun.reflect.generics.reflectiveObjects.WildcardTypeImplimpl interfaceName -> WildcardType
     */
    private Map<T, ? extends Map<K, V>> list;

    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
        //1. 通过填充 方法参数类型反射调用对应方法:如果参数是确定的类型(如Map&List等 则不能指定父类或者顶层父类 HashMap->Map.class->Object.class) 【java.lang.NoSuchMethodException】
        //2. getGenericParameterTypes 为Method 对象api,按顺序返回method 对应形参数组
        //3. 形如 List<? extends xxx> 的Type 类型为,ParameterizedType 而非WildcardType ,但通过ParameterizedType 实例的 getActualTypeArguments 得到的内部泛型类型为WildcardType
        //4. T K V E 在泛型中通常代表具有某种特殊含义的数据类型,单独使用参数类型符号并不能代表该type属于ParameterizedType,但T[] 类型属于 GenericArrayType,
        // {@code GenericArrayType} represents an array type whose component * type is either a parameterized type or a type variable
        //5. List<String>[] 不是ParameterizedType,但同 T[]一样属于 GenericArrayType
        //6. ParameterizedType 除 getActualTypeArguments() 获取实际泛型参数的API外,还有 getRawType() or getOwnType() 分别获取泛型的origin type(List<T> 中<>前的List)和形如Map.Entry<String,String>中 Map为前者的ownType 
        Method method = Test.class.getMethod("testType", List.class, List.class, List.class,
                List.class, List.class, Map.class, int.class, Object[].class, List[].class);
        Type[] types = method.getGenericParameterTypes();//按照声明顺序返回 Type 对象的数组(返回所有形参类型的数组)
        System.out.println("types length::" + types.length);
        for (Type type : types) {
            if(type instanceof WildcardType) {
                System.out.println("WildcardType:::   " + type);
            } else if(type instanceof  ParameterizedType) {
                System.out.println(" --------------- ParameterizedType type ------------ ");
                ParameterizedType pType = (ParameterizedType) type;//最外层都是ParameterizedType

                    Type[] types2 = pType.getActualTypeArguments();//返回表示此类型【实际类型参数】的 Type 对象的数组
                    for (int i = 0; i < types2.length; i++) {
                        Type type2 = types2[i];
                        System.out.println(i + "  类型【" + type2 + "】\t类型接口【" + type2.getClass().getInterfaces()[0].getSimpleName() + "】");
                    }
            } else if(type instanceof GenericArrayType) {
                System.out.println(" --------------- GenericArrayType type ------------ ");
                System.out.println("GenericArrayType type:::   " + type);
            } else if(type instanceof TypeVariable){
                //以上type 均不属于该type
                System.out.println(" --------------- TypeVariable type ------------ ");
                System.out.println("TypeVariable type:::   " + type);
            } else {
                System.out.println(" --------------- else type ------------ ");
                System.out.println("else type:::   " + type);
            }
            //-----------------------------------Field part-----------------------------------------
            System.out.println("-------------- Field part ---------------");
            try {
                //private 变量 即使在本类中直接获取也需要使用declare的方式, 否则 NoSuchFieldException
                Field[] listFs = Test.class.getDeclaredFields();
                for (Field field :
                        listFs) {
                    //getGenericType 同getType 区别:前者获取field 的直接type不包括generic,后者则包括在内 为原有类型+generic类型,如没有generic 则等价于getType
                    Type fieldType = field.getGenericType();
                    System.out.println("getGenericType field type:::" + fieldType);
                    if (fieldType instanceof ParameterizedType) {
                        Type[] typeArguments = ((ParameterizedType) fieldType).getActualTypeArguments();
                        for (int i = 0; i < typeArguments.length; i++) {
                            System.out.println("第  " + i + "  个泛型参数类型::"  + typeArguments[i]);
                            System.out.println("type is TypeVariable ?:: " + (typeArguments[i] instanceof TypeVariable));
                            System.out.println("className -> " + typeArguments[i].getClass() + "impl interfaceName -> " + typeArguments[i].getClass().getInterfaces()[0].getSimpleName());
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * // 去掉泛型 就不属于ParameterizedType(强转报错), T 只是一个符号,不代表泛型
     * 除6/7/8 不属于 ParameterizedType, 其中6/7属于 基本/普通类型 而 8 属于 GenericArrayType
     * 其他属于ParameterizedType
     */
    public <T> void testType(List<String> a1, List<ArrayList<String>> a2, List<T> a3,
                             List<? extends Number> a4, List<ArrayList<String>[]> a5,
                             Map a6, int a7, T[] a8, List<String>[] a9) {
    }
}
上一篇 下一篇

猜你喜欢

热点阅读