Android FastJson泛型类型处理的源码逻辑原理
一、泛型类型处理概述
在Android开发中,JSON数据与Java对象的映射经常涉及泛型类型。FastJson作为高性能的JSON处理库,需要准确识别和处理泛型信息,以确保类型安全和数据正确转换。FastJson通过反射和类型擦除机制,结合自定义的类型解析逻辑,实现了对泛型类型的有效处理。本文将从源码层面深入解析其实现原理。
二、Java泛型的基本概念与挑战
2.1 泛型类型擦除
Java泛型在编译后会进行类型擦除,即泛型参数类型信息在运行时不可直接获取。例如:
List<String> list = new ArrayList<>();
// 编译后泛型信息被擦除,等同于:
List list = new ArrayList();
这种类型擦除机制给JSON反序列化带来了挑战,因为在运行时需要知道具体的泛型参数类型才能正确地将JSON数据转换为Java对象。
2.2 泛型类型表示
Java通过java.lang.reflect.Type
接口及其子接口来表示泛型类型信息:
-
Class
:表示具体的类类型 -
ParameterizedType
:表示参数化类型,如List<String>
-
GenericArrayType
:表示泛型数组类型,如List<String>[]
-
TypeVariable
:表示类型变量,如T
-
WildcardType
:表示通配符类型,如? extends Number
FastJson需要通过这些接口获取和处理泛型类型信息。
三、FastJson泛型处理的核心类与接口
3.1 Type接口及其实现类
FastJson使用Java反射的Type
接口及其实现类来表示和处理泛型类型。
public interface Type {// 类型接口定义
}public class ParameterizedTypeImpl implements ParameterizedType {private final Type rawType; // 原始类型,如Listprivate final Type[] actualTypeArguments; // 实际类型参数,如Stringprivate final Type ownerType; // 所属类型public ParameterizedTypeImpl(Type rawType, Type[] actualTypeArguments, Type ownerType) {this.rawType = rawType;this.actualTypeArguments = actualTypeArguments;this.ownerType = ownerType;}@Overridepublic Type[] getActualTypeArguments() {return actualTypeArguments;}@Overridepublic Type getRawType() {return rawType;}@Overridepublic Type getOwnerType() {return ownerType;}
}
3.2 TypeUtils工具类
TypeUtils
是FastJson中处理类型信息的核心工具类,提供了一系列处理泛型类型的方法。
public class TypeUtils {// 获取集合元素类型public static Type getCollectionItemType(Type type) {if (type instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType) type;Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();if (actualTypeArguments != null && actualTypeArguments.length > 0) {return actualTypeArguments[0];}}return Object.class;}// 获取Map键类型public static Type getMapKeyType(Type type) {if (type instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType) type;Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();if (actualTypeArguments != null && actualTypeArguments.length > 1) {return actualTypeArguments[0];}}return Object.class;}// 获取Map值类型public static Type getMapValueType(Type type) {if (type instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType) type;Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();if (actualTypeArguments != null && actualTypeArguments.length > 1) {return actualTypeArguments[1];}}return Object.class;}// 解析类型字符串为Type对象public static Type parseType(String typeName) {// 类型解析逻辑// ...}
}
四、泛型类型信息的获取
4.1 从字段获取泛型类型
FastJson通过反射获取字段的泛型类型信息。
public class JavaBeanInfo {// 构建JavaBean信息public static JavaBeanInfo build(Class<?> clazz, ParserConfig config) {List<FieldInfo> fieldList = new ArrayList<>();// 获取类的所有字段Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {// 跳过静态字段和transient字段if (Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers())) {continue;}// 获取字段的泛型类型Type genericType = field.getGenericType();// 创建FieldInfo对象FieldInfo fieldInfo = new FieldInfo(field.getName(),field,genericType,field.getType(),0, // 序列化顺序null // JSONField注解);fieldList.add(fieldInfo);}return new JavaBeanInfo(clazz, fieldList);}
}
4.2 从方法获取泛型类型
对于通过getter/setter方法访问的属性,FastJson会从方法的参数类型或返回类型获取泛型信息。
public class JavaBeanInfo {// 构建JavaBean信息public static JavaBeanInfo build(Class<?> clazz, ParserConfig config) {List<FieldInfo> fieldList = new ArrayList<>();// 获取类的所有方法Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {String methodName = method.getName();Class<?> returnType = method.getReturnType();Type genericReturnType = method.getGenericReturnType();// 处理getter方法if (methodName.startsWith("get") && methodName.length() > 3 && returnType != Void.TYPE) {if (method.getParameterTypes().length != 0) {continue;}String propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);Field field = null;try {field = clazz.getDeclaredField(propertyName);} catch (NoSuchFieldException e) {// 忽略}// 创建FieldInfo对象FieldInfo fieldInfo = new FieldInfo(propertyName,field,method,null, // setter方法genericReturnType,returnType,0, // 序列化顺序null // JSONField注解);fieldList.add(fieldInfo);}// 处理setter方法if (methodName.startsWith("set") && methodName.length() > 3 && returnType == Void.TYPE) {Class<?>[] parameterTypes = method.getParameterTypes();if (parameterTypes.length != 1) {continue;}String propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);Field field = null;try {field = clazz.getDeclaredField(propertyName);} catch (NoSuchFieldException e) {// 忽略}// 获取方法的泛型参数类型Type[] genericParameterTypes = method.getGenericParameterTypes();Type genericType = genericParameterTypes[0];// 创建FieldInfo对象FieldInfo fieldInfo = new FieldInfo(propertyName,field,null, // getter方法method,genericType,parameterTypes[0],0, // 序列化顺序null // JSONField注解);fieldList.add(fieldInfo);}}return new JavaBeanInfo(clazz, fieldList);}
}
五、泛型集合类型的处理
5.1 集合类型的反序列化器
FastJson为集合类型提供了专门的反序列化器CollectionDeserializer
,处理泛型集合的反序列化。
public class CollectionDeserializer implements ObjectDeserializer {@Overridepublic <T> T deserialze(JSONParser parser, Type type, Object fieldName) {JSONLexer lexer = parser.getLexer();// 处理JSON数组开始标记if (lexer.token() == JSONToken.BEGIN_ARRAY) {lexer.nextToken();// 创建集合实例Collection<Object> collection = TypeUtils.createCollection(type);// 获取集合元素的泛型类型Type elementType = TypeUtils.getCollectionItemType(type);// 解析数组元素while (lexer.token() != JSONToken.END_ARRAY) {// 根据元素泛型类型解析元素Object element = parser.parseObject(elementType);collection.add(element);// 处理逗号分隔符if (lexer.token() == JSONToken.COMMA) {lexer.nextToken();}}lexer.nextToken();return (T) collection;}// 处理非数组类型的情况// ...throw new JSONException("expect array, but " + lexer.token());}@Overridepublic int getFastMatchToken() {return JSONToken.BEGIN_ARRAY;}
}
5.2 泛型元素的类型转换
在解析集合元素时,FastJson会根据元素的泛型类型进行类型转换。
public class JSONParser {// 解析对象public Object parseObject(Type type) {// 获取类型对应的反序列化器ObjectDeserializer deserializer = config.getDeserializer(type);// 调用反序列化器进行解析return deserializer.deserialze(this, type, null);}// 解析集合元素public Object parseElement(Type elementType) {// 根据元素类型获取反序列化器ObjectDeserializer deserializer = config.getDeserializer(elementType);// 调用反序列化器解析元素return deserializer.deserialze(this, elementType, null);}
}
六、泛型Map类型的处理
6.1 Map类型的反序列化器
FastJson为Map类型提供了专门的反序列化器MapDeserializer
,处理泛型Map的反序列化。
public class MapDeserializer implements ObjectDeserializer {@Overridepublic <T> T deserialze(JSONParser parser, Type type, Object fieldName) {JSONLexer lexer = parser.getLexer();// 处理JSON对象开始标记if (lexer.token() == JSONToken.BEGIN_OBJECT) {lexer.nextToken();// 创建Map实例Map<Object, Object> map = TypeUtils.createMap(type);// 获取Map键和值的泛型类型Type keyType = TypeUtils.getMapKeyType(type);Type valueType = TypeUtils.getMapValueType(type);// 解析Map的键值对while (lexer.token() != JSONToken.END_OBJECT) {// 获取键String keyStr = lexer.stringVal();lexer.nextToken();// 处理冒号分隔符if (lexer.token() != JSONToken.COLON) {throw new JSONException("expect :, but " + lexer.token());}lexer.nextToken();// 根据键类型进行转换Object key = TypeUtils.cast(keyStr, keyType, parser.getConfig());// 根据值类型解析值Object value = parser.parseObject(valueType);// 将键值对添加到Map中map.put(key, value);// 处理逗号分隔符if (lexer.token() == JSONToken.COMMA) {lexer.nextToken();}}lexer.nextToken();return (T) map;}// 处理非对象类型的情况// ...throw new JSONException("expect object, but " + lexer.token());}@Overridepublic int getFastMatchToken() {return JSONToken.BEGIN_OBJECT;}
}
6.2 泛型键值的类型转换
在解析Map的键值对时,FastJson会根据键和值的泛型类型进行类型转换。
public class MapDeserializer implements ObjectDeserializer {@Overridepublic <T> T deserialze(JSONParser parser, Type type, Object fieldName) {// ...// 获取Map键和值的泛型类型Type keyType = TypeUtils.getMapKeyType(type);Type valueType = TypeUtils.getMapValueType(type);// 解析Map的键值对while (lexer.token() != JSONToken.END_OBJECT) {// 获取键String keyStr = lexer.stringVal();lexer.nextToken();// 根据键类型进行转换Object key = TypeUtils.cast(keyStr, keyType, parser.getConfig());// 根据值类型解析值Object value = parser.parseObject(valueType);// 将键值对添加到Map中map.put(key, value);// ...}// ...}
}
七、泛型嵌套类型的处理
7.1 嵌套泛型类型的解析
FastJson能够递归处理嵌套的泛型类型,例如List<List<String>>
。
public class JSONParser {// 解析对象public Object parseObject(Type type) {// 获取当前Token类型int token = lexer.token();if (token == JSONToken.BEGIN_OBJECT) {// 处理JSON对象return parseObject(new LinkedHashMap<>(), type, null);}if (token == JSONToken.BEGIN_ARRAY) {// 处理JSON数组return parseArray(type, null);}// 处理其他类型// ...}// 解析数组private Object parseArray(Type type, Object fieldName) {// 获取集合元素类型Type elementType = TypeUtils.getCollectionItemType(type);// 创建集合实例Collection<Object> collection = TypeUtils.createCollection(type);// 解析数组元素while (lexer.token() != JSONToken.END_ARRAY) {// 递归解析元素,处理嵌套泛型Object element = parseObject(elementType);collection.add(element);// 处理逗号分隔符if (lexer.token() == JSONToken.COMMA) {lexer.nextToken();}}lexer.nextToken();return collection;}
}
7.2 复杂嵌套类型示例
对于复杂的嵌套泛型类型,如Map<String, List<User>>
,FastJson会递归处理每个层级的泛型信息。
public class MapDeserializer implements ObjectDeserializer {@Overridepublic <T> T deserialze(JSONParser parser, Type type, Object fieldName) {// 创建Map实例Map<Object, Object> map = TypeUtils.createMap(type);// 获取Map键和值的泛型类型Type keyType = TypeUtils.getMapKeyType(type);Type valueType = TypeUtils.getMapValueType(type);// 解析Map的键值对while (lexer.token() != JSONToken.END_OBJECT) {// 获取键String keyStr = lexer.stringVal();lexer.nextToken();// 根据键类型进行转换Object key = TypeUtils.cast(keyStr, keyType, parser.getConfig());// 递归解析值,处理嵌套泛型Object value = parser.parseObject(valueType);// 将键值对添加到Map中map.put(key, value);// 处理逗号分隔符if (lexer.token() == JSONToken.COMMA) {lexer.nextToken();}}lexer.nextToken();return (T) map;}
}
八、泛型类型擦除的补偿机制
8.1 通过TypeReference保留泛型信息
FastJson提供了TypeReference
类,用于在运行时保留泛型类型信息。
public class TypeReference<T> {protected final Type type;protected TypeReference() {// 获取子类的泛型参数类型Type superClass = getClass().getGenericSuperclass();if (superClass instanceof Class) {throw new IllegalArgumentException("TypeReference must be subclassed");}ParameterizedType parameterizedType = (ParameterizedType) superClass;this.type = parameterizedType.getActualTypeArguments()[0];}public Type getType() {return type;}
}
使用示例:
TypeReference<List<String>> typeRef = new TypeReference<List<String>>() {};
Type type = typeRef.getType(); // 获取到具体的泛型类型 List<String>
8.2 在反序列化中使用TypeReference
在反序列化时,可以使用TypeReference
来指定具体的泛型类型。
String json = "[\"apple\", \"banana\", \"cherry\"]";
List<String> list = JSON.parseObject(json, new TypeReference<List<String>>() {});
8.3 内部实现原理
在反序列化过程中,FastJson会根据TypeReference
提供的泛型类型信息进行解析。
public class JSON {// 反序列化方法public static <T> T parseObject(String text, TypeReference<T> typeReference) {return parseObject(text, typeReference.getType());}// 反序列化方法public static <T> T parseObject(String text, Type type) {if (text == null || text.length() == 0) {return null;}JSONParser parser = new JSONParser(new JSONScanner(text));return (T) parser.parseObject(type);}
}
九、泛型类型处理的性能优化
9.1 反序列化器缓存
FastJson通过缓存反序列化器来提高泛型类型处理的性能。
public class ParserConfig {private final ConcurrentHashMap<Type, ObjectDeserializer> deserializerCache = new ConcurrentHashMap<>();// 获取反序列化器public ObjectDeserializer getDeserializer(Type type) {ObjectDeserializer deserializer = deserializerCache.get(type);if (deserializer == null) {// 创建反序列化器deserializer = createDeserializer(type);deserializerCache.put(type, deserializer);}return deserializer;}
}
9.2 ASM优化
对于频繁使用的泛型类型,FastJson使用ASM生成高性能的反序列化代码。
public class ASMDeserializerFactory {// 生成泛型集合的反序列化器public ObjectDeserializer createCollectionDeserializer(ParserConfig config, Type type) {// 使用ASM生成字节码// ...// 加载生成的类Class<?> deserializerClass = defineClass("com.alibaba.fastjson.asm.CollectionDeserializer_" + System.identityHashCode(type),bytecode,0,bytecode.length);// 创建反序列化器实例try {return (ObjectDeserializer) deserializerClass.getConstructor(ParserConfig.class, Type.class).newInstance(config, type);} catch (Exception e) {throw new JSONException("create deserializer error", e);}}
}
十、泛型类型处理的应用场景
10.1 网络请求响应处理
在Android开发中,网络请求返回的JSON数据经常需要转换为泛型集合或泛型对象。
// 定义API接口
public interface ApiService {@GET("users")Call<Response<List<User>>> getUsers();
}// 处理响应
Call<Response<List<User>>> call = apiService.getUsers();
call.enqueue(new Callback<Response<List<User>>>() {@Overridepublic void onResponse(Call<Response<List<User>>> call, Response<Response<List<User>>> response) {Response<List<User>> result = response.body();List<User> users = result.getData();// 处理用户列表}@Overridepublic void onFailure(Call<Response<List<User>>> call, Throwable t) {// 处理错误}
});
10.2 本地数据存储与读取
在使用JSON进行本地数据存储和读取时,也需要处理泛型类型。
// 保存数据到SharedPreferences
public void saveData(List<User> users) {String json = JSON.toJSONString(users);SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();editor.putString("users", json);editor.apply();
}// 从SharedPreferences读取数据
public List<User> loadData() {SharedPreferences prefs = getSharedPreferences("data", MODE_PRIVATE);String json = prefs.getString("users", null);if (json != null) {return JSON.parseObject(json, new TypeReference<List<User>>() {});}return new ArrayList<>();
}
十一、泛型类型处理的常见问题与解决方案
11.1 泛型类型擦除导致的问题
由于Java泛型的类型擦除,直接使用泛型类型会丢失类型信息。
解决方案:
- 使用
TypeReference
保留泛型类型信息 - 通过反射获取泛型类型信息
11.2 嵌套泛型处理困难
对于复杂的嵌套泛型类型,处理起来比较困难。
解决方案:
- FastJson通过递归解析嵌套泛型类型
- 使用
TypeReference
明确指定嵌套泛型类型
11.3 自定义泛型类处理
对于自定义泛型类,需要特殊处理。
解决方案:
- 实现自定义反序列化器
- 在反序列化器中处理泛型类型信息
十二、FastJson泛型处理的未来发展
12.1 对Java新特性的支持
随着Java语言的发展,如Records、Sealed Classes等新特性的出现,FastJson可能会进一步优化对这些新特性的泛型支持。
12.2 性能优化持续改进
FastJson团队可能会继续优化泛型类型处理的性能,例如更高效的类型信息缓存和更快的ASM代码生成。
12.3 API简化与增强
未来可能会提供更简洁易用的API来处理泛型类型,减少开发者的使用难度。