使用Gson ExclusionStrategy时遇Stack overflow异常,求助解决方案
解决Gson序列化时的重复字段与栈溢出问题
嘿,我来帮你搞定这个头疼的问题!你遇到的两个异常其实是连锁反应,咱们一步步拆解解决:
1. 先搞清楚「hashCode_字段重复」的根源
这个异常说明你的目标对象(或者它继承的父类)里存在重复命名的hashCode_字段——可能是你自己的类定义里不小心加了两次,也可能是某个第三方依赖库的类和你的类都有这个字段,导致Gson序列化时冲突。
你可以先通过反射快速定位问题字段,比如写个小工具类遍历类的所有字段(包括父类):
public static void printAllFields(Class<?> clazz) { while (clazz != null) { for (Field field : clazz.getDeclaredFields()) { System.out.println(clazz.getSimpleName() + ": " + field.getName()); } clazz = clazz.getSuperclass(); } }
调用这个方法打印你要序列化的对象的所有字段,就能找到重复的hashCode_到底来自哪个类。
2. 修正ExclusionStrategy,避免栈溢出
你之前用ExclusionStrategy后出现栈溢出,大概率是因为策略写得太宽泛,或者没处理循环引用问题:
- 如果盲目排除所有
hashCode_字段,可能不小心排除了某个关键字段,导致Gson在序列化关联对象时陷入无限递归; - 或者你的对象本身存在循环引用(比如A包含B,B又包含A),Gson默认不处理这种情况,会一直递归序列化直到栈溢出。
正确的ExclusionStrategy写法(精准排除重复字段)
只排除你找到的那个重复的hashCode_字段,而不是全局排除:
ExclusionStrategy duplicateFieldStrategy = new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes f) { // 只排除特定类下的hashCode_字段,把YourProblematicClass换成你找到的类 return "hashCode_".equals(f.getName()) && f.getDeclaringClass().equals(YourProblematicClass.class); } @Override public boolean shouldSkipClass(Class<?> clazz) { // 除非确定不需要序列化某个类,否则不要随便返回true return false; } };
处理循环引用导致的栈溢出
如果是循环引用问题,给循环依赖的字段加上@JsonIgnore注解,或者在ExclusionStrategy里排除它:
比如你的类结构是这样:
class A { B b; // 循环引用B } class B { A a; // 循环引用A }
那么给B类里的a字段加上@JsonIgnore,或者在策略里排除:
@Override public boolean shouldSkipField(FieldAttributes f) { // 同时处理重复字段和循环引用 boolean isDuplicateHashCode = "hashCode_".equals(f.getName()) && f.getDeclaringClass().equals(YourProblematicClass.class); boolean isCircularReference = "a".equals(f.getName()) && f.getDeclaringClass().equals(B.class); return isDuplicateHashCode || isCircularReference; }
3. 优化你的convertToJsonString方法
确保你的方法里没有重复序列化的逻辑,比如不要在序列化方法里又调用了对象的某个getter,而getter里又触发了序列化。正确的基础写法应该是:
public static String convertToJsonString(Object obj) { Gson gson = new GsonBuilder() .setExclusionStrategies(duplicateFieldStrategy) // 如果需要格式化输出可以加这个,不需要就去掉 .setPrettyPrinting() .create(); return gson.toJson(obj); }
这样一步步调整,应该就能同时解决重复字段异常和栈溢出问题啦!
内容的提问来源于stack exchange,提问作者Mohammad javani
相关产品推荐
相关产品推荐

