-->

序列化循环对象树 - 的StackOverflowError - 自定义序列代码所需(Serial

2019-09-17 12:27发布

我想提出一个Android应用程序在那里我有一个双向循环对象树,我需要序列填写BLOB字段中SQLite数据库。 但是默认的系列化实现抛出,在我的StackOverflowError(底部堆栈跟踪)。 但是我在编写自定义Java序列化代码,以避免这种情况的经验。

我这个线程( 的StackOverflowError序列化Java中的对象的时候 ),他谈到了问题,而是如何实现它在我的情况我真的没有任何想法:

这是可能的,以限定用于这样的列表类,当第一链路是串行化的,简单地行走的列表,并迭代地串行化每个链路一个writeObject()方法; 这将阻止默认递归机制被使用。

这是我的对象模型(看1 / M,而不是其他标志):

这是我使用序列化对象模型为字节阵列(正确并不重要)的方法:

public byte[] serialize(Object object) {
        byte[] buf = null;
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutput out = new ObjectOutputStream(bos);
            out.writeObject(object);
            out.close();
            buf = bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buf;
    }

自定义序列化功能:

private void writeObject(java.io.ObjectOutputStream out) throws IOException {
    //please help me with this code
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
    //please help me with this code
}

希望有人能帮助我得到这个问题解决了。 任何线索是表示赞赏。

异常堆栈跟踪:

05-25 20:28:16.231: E/AndroidRuntime(14451): FATAL EXCEPTION: main
05-25 20:28:16.231: E/AndroidRuntime(14451): java.lang.StackOverflowError
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.util.IdentityHashMap.findIndex(IdentityHashMap.java:419)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.util.IdentityHashMap.get(IdentityHashMap.java:371)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.dumpCycle(ObjectOutputStream.java:471)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1739)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.util.ArrayList.writeObject(ArrayList.java:651)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.lang.reflect.Method.invokeNative(Native Method)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.lang.reflect.Method.invoke(Method.java:507)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.util.ArrayList.writeObject(ArrayList.java:651)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.lang.reflect.Method.invokeNative(Native Method)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.lang.reflect.Method.invoke(Method.java:507)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject

Answer 1:

Java序列化正确处理循环图,但长的列表是一个问题。

如果我没有理解正确的话,你的问题是一个比你链接的文章中有些不同,导致有关链表这篇文章的会谈没有适当的writeObject。虽然你目前正在使用的ArrayList,这已存储的对象作为平面阵列,并也有适当的writeObject。

但如果我这样做是正确,什么情况是或多或少这样的:

你开始序列化对象的,该序列中遇到一个长长的名单,采取的第一个元素和序列化对象B,对象B也有一个长长的清单,它需要的第一个元素,说这是一个再次,因为它已经被序列化它跳过A,因此它不会在无限循环中结束,但随后进行到第二对象在B的列表,这是C,也C有一个长列表,前两个元素是A和B再次,所以他们被跳过,第三是d,它也有一个列表....和SOOOO上。

由于这些步骤每一个都在堆栈斯特斯几行,它填满了,即使他们有适当的writeObject方法所有的ArrayList。

这可能是情况下,如果这些名单大规模进入相对“大”的数字相比,你有运行。 这就是为什么我问的评论。 也许一个办法可以解决,避免序列化一些列表(使它们短暂的),以及“部分”反序列化后重建他们。



文章来源: Serialize cyclic object tree – StackOverflowError – custom serialization code needed