You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:44:25