在使用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
获取到了真实的类型,就可以实现对泛型的反序列化了。