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

使用Gson的fromJson时myNumber字段值被转为0的问题及解决

问题:GSON转换后POJO数值字段始终为0,数值丢失

问题重现代码

POJO类

public class MyPojo {
  String id;
  double myNumber;
}

JSON数据

{
    "id": "id1",
    "my_number": 10.0
}

转换代码

// from为上述JSON字符串
Map<String, Object> myData = gson.fromJson(new String(from, StandardCharsets.UTF_8), Map.class);
JsonElement jsonElement = gson.toJsonTree(myData);  // 检查发现此处包含"myNumber: 10"
MyPojo pojo = gson.fromJson(jsonElement, MyPojo.class);  // 此处myNumber值为0

转换后myNumber字段始终为0,即使将JSON中的字段名改为myNumber也无法解决。


问题原因

  1. POJO字段访问权限不足:GSON默认依赖反射访问POJO字段,你的id和myNumber是默认包访问权限,GSON无法直接写入值,因此字段保留默认初始值(double类型默认值为0.0)。
  2. 下划线与驼峰命名不匹配:JSON中的my_number是下划线命名,POJO中的myNumber是驼峰命名,默认GSON不会自动映射这种命名差异,导致字段无法匹配赋值。
  3. 中间转换冗余且易出问题:先转Map再转JsonElement的操作完全多余,虽然你检查到JsonElement中有值,但权限问题导致最终无法写入POJO。

修复方案

方案1:修改POJO字段为public

直接开放字段访问权限,让GSON通过反射直接赋值:

public class MyPojo {
  public String id;
  public double myNumber;
}

方案2:添加Getter/Setter方法

保持字段权限不变,提供标准的getter和setter方法,GSON会通过这些方法完成赋值:

public class MyPojo {
  String id;
  double myNumber;

  public String getId() { return id; }
  public void setId(String id) { this.id = id; }

  public double getMyNumber() { return myNumber; }
  public void setMyNumber(double myNumber) { this.myNumber = myNumber; }
}

方案3:配置GSON支持下划线转驼峰命名

如果需要保留JSON的下划线命名风格,创建GSON实例时指定字段命名策略,自动映射下划线到驼峰:

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .create();
// 使用该gson实例进行后续所有转换操作

方案4:跳过冗余中间转换,直接JSON转POJO

完全不需要先转Map再转JsonElement,一步完成转换既简洁又避免中间环节问题:

// from为JSON字符串
MyPojo pojo = gson.fromJson(new String(from, StandardCharsets.UTF_8), MyPojo.class);

内容的提问来源于stack exchange,提问作者ritratt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:25:18