如何将三种不同类型的序列化方法泛化为单一通用方法?
嘿,我完全懂你现在的烦恼——三个逻辑几乎一模一样的方法,只是分别处理单个对象、列表和数组,重复代码不仅冗余,后续维护也麻烦。别发愁,咱们用Java泛型+Gson的TypeToken就能打造一个通用的序列化/反序列化方法,一次性搞定所有场景!
先上合并后的通用方法代码
import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.mongodb.util.JSON; import java.lang.reflect.Type; public class GenericSerializer { // 假设你的全局Gson实例已经定义,这里给出示例 private static final Gson GSON_INSTANCE = new Gson(); /** * 通用序列化工具:将任意输入对象(单个Document、List<Document>、Document数组)转为指定类型的实例/集合 * @param input 待转换的输入对象 * @param targetType 目标类型的Type(支持泛型集合、数组、单个对象) * @return 转换后的目标类型实例 * @param <T> 目标类型的泛型参数 */ public static <T> T genericSerializer(Object input, Type targetType) { // 统一序列化输入为JSON字符串 String json = JSON.serialize(input); // 利用Gson根据目标Type反序列化 return GSON_INSTANCE.fromJson(json, targetType); } // 可选重载:针对单个对象和数组,简化调用(无需手动构建TypeToken) public static <T> T genericSerializer(Object input, Class<T> targetClass) { return genericSerializer(input, (Type) targetClass); } }
怎么调用这个通用方法?
我给你举三个典型场景的例子,对应你原来的三个方法:
1. 单个Document转目标类实例
Document singleDoc = new Document("username", "LaurentKavaba") .append("email", "laurent@example.com"); // 直接传入目标类的Class即可 User singleUser = GenericSerializer.genericSerializer(singleDoc, User.class);
2. List转List<目标类>
这里需要用TypeToken来获取带泛型信息的Type(因为Class无法表示List<User>这种泛型类型):
List<Document> docList = Arrays.asList( new Document("username", "Alice"), new Document("username", "Bob") ); // 用匿名内部类创建TypeToken,获取List<User>的Type Type userListType = new TypeToken<List<User>>(){}.getType(); List<User> userList = GenericSerializer.genericSerializer(docList, userListType);
3. Document数组转目标类数组
直接传入数组的Class即可,和单个对象的调用方式一致:
Document[] docArray = { new Document("username", "Charlie"), new Document("username", "Diana") }; User[] userArray = GenericSerializer.genericSerializer(docArray, User[].class);
为什么这个通用方法能 work?
- 统一序列化逻辑:MongoDB的
JSON.serialize()方法本身就支持序列化任意Java对象(包括单个对象、集合、数组),所以第一步的序列化可以完全复用。 - 泛型+TypeToken解决泛型类型擦除:Java的泛型会在编译时擦除,
Class无法表示List<User>这种带泛型参数的类型,而TypeToken能帮我们在运行时保留泛型信息,让Gson正确反序列化为目标集合。 - 重载方法简化调用:针对单个对象和数组的场景,提供重载方法,不用每次都手动写
TypeToken,提升代码可读性。
一些注意事项
- 确保你的目标类(比如
User)有无参构造函数,Gson默认需要这个来创建实例;如果没有,可以通过自定义TypeAdapter解决。 - 如果Document的字段名和目标类的字段名不匹配,可以用Gson的
@SerializedName注解做映射。 - 如果有自定义的序列化/反序列化逻辑,提前在
GSON_INSTANCE中注册对应的TypeAdapter即可。
内容的提问来源于stack exchange,提问作者LaurentKavaba
相关产品推荐
相关产品推荐

