在 Java 中,序列化使得在流中读取和写入对象变得非常容易。例如,以下代码片段基本上是将对象写入流所需的全部内容:
ObjectOutputStream oos = ... //Initialize your output stream
Object toWrite = ... //Initialize what you want to write here
oos.writeObject(toWrite); //Writes the object to the stream
oos.flush();
这会工作得很好,前提是toWrite
的类实现了Serializable
接口,并且所有toWrite
's non-transient
成员变量也是Serializable
。换句话说,您尝试通过toWrite
参考必须是Serializable
。假设这段代码的唯一问题是里面的东西toWrite
isn't Serializable
.
如果层次结构不完全Serializable
,调用oos.writeObject(toWrite)
抛出一个java.io.NotSerializableException
。这一切都很好,只是异常并没有为您提供快速解决问题所需的一切。它会告诉您哪些类无法序列化。您的堆栈跟踪可能如下所示:
java.io.NotSerializableException: some.package.and.ClassIDidntExplicitlyReference
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
...
at my.package.MyClass.codeThatWroteTheOffendingObject(MyClass.java:###)
这会为您指明正确的方向,但在涉及由toWrite
,并不总是清楚有问题的类引用来自哪里。假设我分配toWrite
到一个实例MyClass
和我的例子MyClass
有一个名为的成员对象引用nonSerializableReference
已被设置为一个实例ClassIDidntExplicitlyReference
,这不是Serializable
。我希望看到类似以下内容的打印结果:
my.package.MyClass.nonSerializableReference instanceof some.package.and.ClassIDidntExplicitlyReference
我知道这个问题可能没有快速解决方案,并且可能涉及使用反射。这里有人以前做过这件事吗?如果是的话,您介意分享您的见解吗?
Answer
我最终使用了 ReflectionField
and Modifier
类来查找路径。不幸的是,我无法分享我的代码(违反公司政策),但我可以向您展示我的输出。类 A 持有 B 的实例,B 持有 C 的实例,C 持有 D 的实例。所有这些都是Serializable
除了 D 之外。我最终使用深度优先搜索来查找路径:
A.b ->
B.c ->
C.d instanceof class D
如果我做C.d
暂时的,搜索没有结果。很酷!