为什么使用TypeReference

在使用fastJson的时候对于泛型的反序列化很多场景下都会使用到TypeReference,例如:

 public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");

        JSONObject o = new JSONObject();
        o.put("k",list);

        List<String> types = o.getObject("k",List.class);
        System.out.println(JSON.toJSONString(types));

        List<String> types2 = o.getObject("k",new TypeReference<List<String>>(){});
        System.out.println(JSON.toJSONString(types2));
    }

使用TypeReference可以明确的指定反序列化的类型,具体实现逻辑参考TypeReference的构造函数

  protected TypeReference(){
        Type superClass = getClass().getGenericSuperclass();
		//getActualTypeArguments,获取父类真实的泛型类型
        Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];

        Type cachedType = classTypeCache.get(type);
        if (cachedType == null) {
            classTypeCache.putIfAbsent(type, type);
            cachedType = classTypeCache.get(type);
        }

        this.type = cachedType;
    }

new TypeReference<List>(){}创建了一个继承TypeReference的匿名子类,在其构造函数中拿到了泛型对应Type(java.lang.reflect.ParameterizedType)。
ParameterizedType是一个记录类型泛型的接口, 继承自Type, 一共三方法:

  • Type[] getActualTypeArguments(); //返回泛型类型数组
  • Type getRawType(); //返回原始类型Type
  • Type getOwnerType(); //返回 Type 对象,表示此类型是其成员之一的类型。

例如 Map<String,String> 对应的ParameterizedType三个方法分别取值如下:

  • [class java.lang.String, class java.lang.String]
  • interface java.util.Map
  • null
    TypeReference的存在是因为java中子类可以获取到父类泛型的真实类型:
public class TypeReferenceKest {

    public static void main(String[] args) {
        IntMap intMap = new IntMap();

        System.out.println(intMap.getClass().getSuperclass());

        Type type = intMap.getClass().getGenericSuperclass();
        if(type instanceof ParameterizedType){
            ParameterizedType p = (ParameterizedType) type;
            for (Type t : p.getActualTypeArguments()){
                System.out.println(t);
            }
        }

        System.out.println("=====newclass=====");
        HashMap<String,Integer> newIntMap = new HashMap<>();

        System.out.println(newIntMap.getClass().getSuperclass());

        Type newClassType = newIntMap.getClass().getGenericSuperclass();
        if(newClassType instanceof ParameterizedType){
            ParameterizedType p = (ParameterizedType) newClassType;
            for (Type t : p.getActualTypeArguments()){
                System.out.println(t);
            }
        }

        System.out.println("=====subclass=====");
        HashMap<String,Integer> subIntMap = new HashMap<String,Integer>(){};

        System.out.println(subIntMap.getClass().getSuperclass());

        Type subClassType = subIntMap.getClass().getGenericSuperclass();
        if(subClassType instanceof ParameterizedType){
            ParameterizedType p = (ParameterizedType) subClassType;
            for (Type t : p.getActualTypeArguments()){
                System.out.println(t);
            }
        }
    }


    public static class IntMap extends HashMap<String,Integer> {
    }
}

输出:

class java.util.HashMap
class java.lang.String
class java.lang.Integer
=====newclass=====
class java.util.AbstractMap
K
V
=====subclass=====
class java.util.HashMap
class java.lang.String
class java.lang.Integer

获取到了真实的类型,就可以实现对泛型的反序列化了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值