新增int字段后Gson抛出IllegalStateException异常求助
问题排查与解决方案
核心原因分析
- 存储JSON存在不一致性:部分设备存储的JSON字符串中,
addedVar对应的键已存在,但值为数组类型(而非新增后的int类型)——可能是之前版本代码在特定场景下错误写入了数组值,或是多版本迭代中出现的存储兼容问题。 - @Since注解生效逻辑误解:Gson的
@Since(1.1)+setVersion(1.0)组合,仅当JSON中addedVar字段不存在时才会忽略该字段;若JSON中已存在该字段但类型不匹配,Gson仍会尝试解析并抛出类型不匹配异常。部分设备未出问题,大概率是这些设备存储的JSON原本就没有addedVar字段。 - Gson版本兼容性问题:不同设备依赖的Gson版本可能存在差异,旧版本Gson对
@Since注解的处理存在bug,导致setVersion(1.0)未正确忽略addedVar字段。
具体解决方案
- 定位异常字段:捕获异常时打印报错的JSON字符串,定位到提示的列位置(如112/120),确认该位置的键值对是否为
addedVar,以及值的类型是否为数组。 - 强制忽略不兼容字段:若确认是
addedVar类型不匹配,确保@Since注解正确使用的同时,通过GsonBuilder配置兼容实例:
若旧版本Gson对// 创建兼容旧版本的Gson实例 Gson oldVersionGson = new GsonBuilder() .setVersion(1.0) .create();@Since支持不佳,可改用@Expose注解配合字段过滤:// Schedule类中新增字段 @Expose(serialize = false, deserialize = false) @Since(1.1) private int addedVar; // 创建旧版本兼容Gson Gson oldVersionGson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create(); - 自定义类型适配兼容数组场景:若部分JSON中
addedVar确实是数组,编写TypeAdapter处理类型兼容:
注册适配器到Gson:public class ScheduleTypeAdapter extends TypeAdapter<Schedule> { private final Gson gson = new Gson(); @Override public void write(JsonWriter out, Schedule value) throws IOException { gson.getAdapter(Schedule.class).write(out, value); } @Override public Schedule read(JsonReader in) throws IOException { JsonObject jsonObject = gson.getAdapter(JsonObject.class).read(in); if (jsonObject.has("addedVar")) { JsonElement element = jsonObject.get("addedVar"); if (element.isJsonArray()) { JsonArray array = element.getAsJsonArray(); jsonObject.add("addedVar", array.isEmpty() ? new JsonPrimitive(0) : array.get(0)); } } return gson.fromJson(jsonObject, Schedule.class); } }Gson compatibleGson = new GsonBuilder() .registerTypeAdapter(Schedule.class, new ScheduleTypeAdapter()) .create(); - 检查异常捕获逻辑:确保解析流程是先尝试新版本Gson,捕获
IllegalStateException后再用旧版本兼容Gson解析同一JSON字符串,避免捕获范围错误或解析对象不一致。
内容的提问来源于stack exchange,提问作者Jorn Rigter
相关产品推荐
相关产品推荐

