天天看點

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