美文网首页
Java Type 体系简单认知

Java Type 体系简单认知

作者: summerlines | 来源:发表于2020-12-28 11:03 被阅读0次
    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) {
        }
    }
    

    相关文章

      网友评论

          本文标题:Java Type 体系简单认知

          本文链接:https://www.haomeiwen.com/subject/fcliyktx.html