TypeParameterResolver使用

ClassA

import lombok.Data;

import java.util.List;
import java.util.Map;

@Data
public class ClassA<K, V> {
    protected Map<K, V> map;

    protected List<K> list;
}

SubClassA

public class SubClassA<T> extends ClassA<T, T> {

}

demo


import org.apache.ibatis.reflection.TypeParameterResolver;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * java.lang.Class的getTypeParameters()--获取类的泛型的类型(如java.util.List<E>中的E)
 *
 * ParameterizedType 表示的是参数化类型,例如 List<String>、 Map<Integer,String>、 Service<User>这种带有泛型的类型。
 *     *  Type getRawType()一一返回参数化类型中的原始类型,例如 List<String>的原始类型为 List。
 *     *  Type[] getActualTypeArguments()一一获取参数化类型的类型变量或是实际类型列表,
 *        例如 Map<Integer, String>的实际泛型列表 Integer和 String。
 *        需要注意的是,该列表的元素类型都是 Type,也就是说,可能存在多层嵌套的情况。
 *     *  Type getOwnerType()一一返回是类型所属的类型,例如存在 A<T>类,其中定义了 内部类 InnerA<I>,
 *          则 InnerA<I>所属的类型为 A<T>,如果是顶层类型则返回 null。
 *          例: Map<K,V>接口与 Map.Entry<K,V>接口 , Map<K,V> 接口是 Map.Entry<K,V>接口的所有者。
 *     * String getTypeName()一一调用toString [rawType=, ownerType=, actualTypeArguments=]
 *
 * TypeVariable 表示的是类型变量 如:T ,它用来反映在 JVM 编译该泛型前的信息。例如 List<T> 中的 T就是类型变量,
 *    它在编译时需被转换为一个具体的类型后才能正常使用。
 *    * Type[] getBounds()一一获取类型变量的上边界,如果未明确声明上边界则默认为
 *              Object。 例如 class Test<K extends Person>中 K 的上界就是 Person。
 *    * D getGenericDeclaration()一一获取声明该类型变量的原始类型,
 *          例如 class Test<K extends Person>中的原始类型是 Test。
 *    * String getNameO一一获取在源码中定义时的名字,上例中为 K。
 *
 * GenericArrayType 表示的是数组类型且组成元素是 ParameterizedType 或 TypeVariable. 例如 List<String>[]或 T[]。
 *       该接 口只有 Type getGenericComponentType()一个方法,它 返回数组的组成元素。
 *
 * WildcardType 表示的是通配符泛型,例如? extends Number 和? super Integer。 WildcardType 接口有两个方法,分别是:
 *    * Type[] getUpperBounds()一一-返回泛型变量的上界。
 *    * Type[] getLowerBounds()一-返回泛型变量的下界。
 * {@link TypeParameterResolver}
 */
public class TypeParameterResolverDemo {
    SubClassA<Long> sa = new SubClassA<>();

    public static void main(String...args) throws Exception{
        Field f = ClassA.class.getDeclaredField("map");
        System.out.println(f.getGenericType());
        // 字段类似是否是参数化类型
        System.out.println(f.getGenericType() instanceof ParameterizedType);
        //java.util.Map<K, V>
        //true

        // 解析 SubClassA<Long>中的 map 字段
        Type type = TypeParameterResolver.resolveFieldType(f,
                ParameterizedTypeImpl.make(SubClassA.class, new Type[]{Long.class}, TypeParameterResolverDemo.class));
        System.out.println(type.getClass());
        // 解析 SubClassA<Long>中的 list 字段 包装成ParameterizedTypeImpl
        Type type1 = TypeParameterResolver.resolveFieldType(ClassA.class.getDeclaredField("list"),
                TypeParameterResolverDemo.class.getDeclaredField("sa").getGenericType());
        System.out.println(type1.getClass());
        //class org.apache.ibatis.reflection.TypeParameterResolver$ParameterizedTypeImpl

        // 返回参数化类型中的原始类型
        System.out.println(((ParameterizedType) f.getGenericType()).getRawType()); //interface java.util.Map
        System.out.println(((ParameterizedType) type).getRawType()); // interface java.util.Map
        // 返回外部类类型
        System.out.println(((ParameterizedType)type).getOwnerType()); //null

        for (Type typeArgument : ((ParameterizedType) type).getActualTypeArguments()) {
            System.out.println(typeArgument);
        }
        //class java.lang.Long
        //class java.lang.Long
        for (Type typeArgument : ((ParameterizedType) f.getGenericType()).getActualTypeArguments()) {
            System.out.println(typeArgument);
        }
        //K
        //V
        System.out.println(((ParameterizedType) type).getTypeName());
        //ParameterizedTypeImpl [rawType=interface java.util.Map, ownerType=null, actualTypeArguments=[class java.lang.Long, class java.lang.Long]]
        System.out.println(((ParameterizedType) type1).getTypeName());
        //ParameterizedTypeImpl [rawType=interface java.util.List, ownerType=null, actualTypeArguments=[class java.lang.Long]]
    }
}

posted @ 2020-10-16 13:42  fly_bk  阅读(159)  评论(0编辑  收藏  举报