Gson序列化Farm对象报错:DecimalFormat重复JSON字段求助
你的问题核心出在Sheep类中未标记为transient的SimpleDateFormat sdf字段上:Gson在序列化Sheep对象时,会尝试递归序列化这个工具类实例,但SimpleDateFormat的父类结构里存在重复命名的字段(maximumIntegerDigits同时在DecimalFormat及其父类中定义),直接触发了字段冲突异常。另外的非法反射警告,也是因为旧版Gson需要访问SimpleDateFormat的私有内部字段来完成序列化操作。
下面是分步骤的修复方案:
1. 阻止Gson序列化SimpleDateFormat实例
sdf只是用来格式化日期的工具类,完全不需要被序列化到JSON中。你有两种方式处理它:
- 直接标记为
transient,让Java序列化机制跳过它:
public class Sheep implements Serializable { // 其他字段保持不变... private transient SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); // 注意:月份格式是大写MM,小写mm代表分钟,你这里大概率写错了! }
- 如果你依赖
@Expose注解控制序列化字段,也可以用注解明确禁止序列化:
@Expose(serialize = false, deserialize = false) private SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
(使用这种方式需要在创建Gson实例时添加.excludeFieldsWithoutExposeAnnotation()配置)
2. 正确处理Date字段的序列化(可选但关键)
你现在给所有Date字段加了transient,这会导致这些日期数据完全不会出现在JSON结果里。如果你的需求是把日期序列化为可读的字符串(比如"dd.MM.yyyy"格式),而非直接忽略,建议用自定义Gson类型适配器替代transient:
步骤2.1 编写Date类型适配器
public class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> { private final SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy"); @Override public JsonElement serialize(Date date, Type typeOfSrc, JsonSerializationContext context) { return new JsonPrimitive(dateFormat.format(date)); } @Override public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { try { return dateFormat.parse(json.getAsString()); } catch (ParseException e) { throw new JsonParseException("日期格式错误", e); } } }
步骤2.2 注册适配器到Gson实例
Gson g = new GsonBuilder() .setPrettyPrinting() .registerTypeAdapter(Date.class, new DateTypeAdapter()) // 若使用@Expose注解,需添加此行 // .excludeFieldsWithoutExposeAnnotation() .create();
步骤2.3 移除Date字段的transient修饰符
现在可以把所有Date字段的transient去掉,让Gson用自定义适配器完成序列化:
@SerializedName("birthDate") @Expose private Date birthDate = null; @SerializedName("sellingDate") @Expose private Date sellingDate = null; // 其他Date字段同理修改...
3. 解决非法反射访问警告
这个警告是因为你使用的Gson 2.8.5版本未适配Java 9+的模块系统。最简单的解决方法是升级Gson到2.9.0及以上版本,新版本已经修复了这个兼容性问题。如果用Maven管理依赖,更新pom.xml:
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.10.1</version> <!-- 最新稳定版 --> </dependency>
完成以上修改后,你的序列化代码应该能正常生成合法的JSON文件,同时不会再抛出异常和警告。
内容的提问来源于stack exchange,提问作者Saleh Abusalah

