天天看点

fastjson为何使用TypeReference?(上)1 核心接口及类

1 核心接口及类

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构造器
fastjson为何使用TypeReference?(上)1 核心接口及类

1.1 ParameterizedType接口

ParameterizedType是一个记录类型泛型的接口, 继承自Type, 一共三接口

Type[] getActualTypeArguments

核心接口,返回泛型类型数组, 该接口可获取父类实际泛型类型,返回的Type数组对象表示该类型的实际类型参数。

Type getRawType()

返回原始类型Type

Type getOwnerType()

返回 Type 对象,表示此类型是其成员之一的类型。

fastjson为何使用TypeReference?(上)1 核心接口及类

比如

Map

响应ParameterizedType三个接口的返回值如下:

  • [class java.lang.String, class java.lang.String]
  • interface java.util.Map
  • null

fastjson对其的实现类

fastjson为何使用TypeReference?(上)1 核心接口及类

一般使用如下

new TypeReference<List<String>>(){}      

创建一个TypeReference的匿名类,在其构造器中拿到泛型对应Type(java.lang.reflect.ParameterizedType)。

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> {
    }
}