gson.toJson()抛出StackOverflowError
我想从我的对象生成一个JSONstring:
Gson gson = new Gson(); String json = gson.toJson(item);
每当我尝试做到这一点,我得到这个错误:
14:46:40,236 ERROR [[BomItemToJSON]] Servlet.service() for servlet BomItemToJSON threw exception java.lang.StackOverflowError at com.google.gson.stream.JsonWriter.string(JsonWriter.java:473) at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:347) at com.google.gson.stream.JsonWriter.value(JsonWriter.java:440) at com.google.gson.internal.bind.TypeAdapters$7.write(TypeAdapters.java:235) at com.google.gson.internal.bind.TypeAdapters$7.write(TypeAdapters.java:220) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:200) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60) at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:843)
这些是我的BomItem类的属性:
private int itemId; private Collection<BomModule> modules; private boolean deprecated; private String partNumber; private String description; //LOB private int quantity; private String unitPriceDollar; private String unitPriceEuro; private String discount; private String totalDollar; private String totalEuro; private String itemClass; private String itemType; private String vendor; private Calendar listPriceDate; private String unitWeight; private String unitAveragePower; private String unitMaxHeatDissipation; private String unitRackSpace;
我引用的BomModule类的属性:
private int moduleId; private String moduleName; private boolean isRootModule; private Collection<BomModule> parentModules; private Collection<BomModule> subModules; private Collection<BomItem> items; private int quantity;
任何想法是什么导致这个错误? 我该如何解决?
如果你有一个循环引用,这可能会发生。
BomModule
引用了你的父对象吗?
当我有一个Log4Jlogging器作为一个类的属性时,我有这个问题,如:
private Logger logger = Logger.getLogger(Foo.class);
这可以通过使logging器static
或简单地通过将其移动到实际function来解决。
SLaks说,如果你的对象有循环引用,StackOverflowError会发生。
要解决这个问题,你可以使用TypeAdapter作为你的对象。
例如,如果只需要从对象中生成String,则可以使用如下的适配器:
class MyTypeAdapter<T> extends TypeAdapter<T> { public T read(JsonReader reader) throws IOException { return null; } public void write(JsonWriter writer, T obj) throws IOException { if (obj == null) { writer.nullValue(); return; } writer.value(obj.toString()); } }
并像这样注册它:
Gson gson = new GsonBuilder() .registerTypeAdapter(BomItem.class, new MyTypeAdapter<BomItem>()) .create();
或者像这样,如果你有接口,并想要使用适配器的所有子类:
Gson gson = new GsonBuilder() .registerTypeHierarchyAdapter(BomItemInterface.class, new MyTypeAdapter<BomItemInterface>()) .create();
如果你正在使用Realm,并且出现这个错误,并且出现问题的对象扩展了RealmObject,那么不要忘记在通过GSON进行序列化之前,先执行realm.copyFromRealm(myObject)
创build一个没有所有Realm绑定的副本。
我错过了这一堆只是一个被复制的对象之一…花了我很长时间才意识到,因为堆栈跟踪不会命名对象的类/types。 事情是,这个问题是由循环引用引起的,但它是RealmObject基类中的循环引用,而不是您自己的子类,这使得更难以发现!
我也有同样的问题。 在我的情况下,原因是我的序列化类的构造函数采取上下文variables,如下所示:
public MetaInfo(Context context)
当我删除这个参数时,错误消失了。
public MetaInfo()
当你在超类中有一个logging器时,这个错误是很常见的。 正如@Zar之前所build议的,您可以使用静态为您的logging器字段,但这也适用:
protected final transient Logger logger = Logger.getLogger(this.getClass());
PS大概它会工作,并与@Expose注释检查更多关于这里: https ://stackoverflow.com/a/7811253/1766166
在Android中,gson堆栈溢出竟然是Handler的声明。 将它移动到一个没有被反序列化的类。
根据Zar的build议,当在另一段代码中发生这种情况时,我使得处理程序是静态的。 使处理程序静态工作。
BomItem
引用BOMModule
( Collection<BomModule> modules
), BOMModule
引用BOMItem
( Collection<BomItem> items
)。 Gson库不喜欢循环引用。 从你的类中移除这个循环依赖。 我也曾经用gson lib面临同样的问题。