Java中的Type知多少?(下)

Java中的Type知多少?(下)

点击《Java中的Type知多少》上篇地址

入门

从spring framework 4.0开始,spring引入了ResolvableType类来完成对java中Type的封装。
下面我基于spring提供的ResolvableType改写《Java中的Type知多少》上篇的所有示例。

ParameterizedType示例

public class TypeApplication{

    public Map<String,Integer> field;

    public static void main(String[] args) throws NoSuchFieldException {
        //通过反射获取Field
        Field field = TypeApplication.class.getField("field");
        
        ResolvableType resolvableType = ResolvableType.forField(field);

        //通过getGenerics方法获取泛型的实际类型
        //key 和 value Type都被包装成ResolvableType
        ResolvableType[] generics = resolvableType.getGenerics();

        for(ResolvableType type : generics){
            //通过resolve获取Class类型
            Class actType = type.resolve();
            //分别输出:
            //class java.lang.String
            //class java.lang.Integer
            System.out.println(actType.toString());
        }
    }
}

GenericArrayType示例

public class TypeApplication{

    public List<String>[] field;

    public static void main(String[] args) throws NoSuchFieldException {
        //通过反射获取Field
        Field field = TypeApplication.class.getField("field");

        ResolvableType resolvableType = ResolvableType.forField(field);
    
        //判断是否是array
        if(resolvableType.isArray()){
            
            //如果是array,获取成分类型,成分类型也被包装成ResolvableType -> List<String>
            ResolvableType componentType = resolvableType.getComponentType();

            //获取List<String>中的String类型
            ResolvableType[] generics = componentType.getGenerics();

            for(ResolvableType type : generics){
                Class actType = type.resolve();
                
                //输出:
                // class java.lang.String
                System.out.println(actType);
            }
        }
    }
}

TypeVariable示例

public class TypeApplication<T extends  Number & Cloneable>{

    public T field;

    public static void main(String[] args) throws NoSuchFieldException {
        //通过反射获取Field
        Field field = TypeApplication.class.getField("field");

        ResolvableType resolvableType = ResolvableType.forField(field);

        Class boundType = resolvableType.resolve();
        
        //这里比较遗憾,对于TypeVariable类型的resolve,我们只可以拿到bounds数组的[0]元素
        //输出:
        // class java.lang.Number
        System.out.println(boundType.toString());
        
   }
}

WildcardType

public class TypeApplication<T extends  Number & Cloneable>{

    public Map<? extends Number,? super String> field;

    public static void main(String[] args) throws NoSuchFieldException {
        //通过反射获取Field
        Field field = TypeApplication.class.getField("field");

        ResolvableType resolvableType = ResolvableType.forField(field);

        //通过getGenerics获取map的key与value的类型:WildcardType,包装成ResolvableType
        ResolvableType[] generics = resolvableType.getGenerics();

        for(ResolvableType type : generics){
            //分别resolve Key 与 Value的类型,有上界优先上界(如果上界是Object认为是无上界),无上界就是下界
            //同样只能解析一个上界或下界
            Class classType = type.resolve();

            //分别输出:
            // class java.lang.Number
            // class java.lang.String
            System.out.println(classType.toString());
        }
    }
}

如何构造ResolvableType

在上面的示例中我们通过forField构造ResolvableType,其实还可以通过以下方法构造

  • forClass
    通过Class构造
  • forClassWithGenerics
    通过Class加泛型类型构造
  • forInstance
    通过实例构造
  • forField
    通过Field构造
  • forConstructorParameter
    通过构造函数参数构造
  • forMethodReturnType
    通过方法返回类型构造
  • forMethodParameter
    通过方法参数构造
  • forArrayComponent
    通过成分类型构造array
  • forType
    直接通过type构造

通过示例进一步了解ResolvableType

public class DemoApplication{

    Map<String,BigDecimal> map;

    public static void complex(List<Map<String,Double>> list){
    }
    public static void main(String[] args) throws NoSuchMethodException {

        //通过field构造 ResolvableType
        ResolvableType  resolvableType = ResolvableType.forField(ReflectionUtils.findField(DemoApplication.class,"map"));

        //输出:
        //class java.lang.String
        //class java.math.BigDecimal
        for(ResolvableType t : resolvableType.getGenerics()){
            System.out.println(t.resolve().toString());
        }

        //相当于构建了一个Map<Long,BigDecimal>的Type
        resolvableType = ResolvableType.forClassWithGenerics(Map.class,Long.class,BigDecimal.class);

        //输出:interface java.util.Map
        System.out.println(resolvableType.resolve().toString());

        //输出:
        // class java.lang.Long
        // class java.math.BigDecimal
        for(ResolvableType t : resolvableType.getGenerics()){
            System.out.println(t.resolve().toString());
        }

        ResolvableType stringToBigDecimalConvert = ResolvableType.forType(StringToBigDecimalConvert.class);

        ResolvableType converter = ResolvableType.forType(Converter.class);

        //true 相当于 Converter.class.isAssignableFrom(StringToBigDecimalConvert.class)
        boolean ret = converter.isAssignableFrom(stringToBigDecimalConvert);

        //来个复杂的
        ResolvableType complex = ResolvableType.forMethodParameter(ReflectionUtils.findMethod(DemoApplication.class,"complex",List.class),0);

        System.out.println(complex.resolve().toString());//输出:interface java.util.List

        //取下double类型
        ResolvableType doubleType = complex.getGeneric(0,1);
        System.out.println(doubleType); //输出:java.lang.Double
    }
}

更多内容,关注《超哥spring源码解析》
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值