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
transient
Serializable
toWrite
Serializable
toWrite
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
この問題にはおそらく迅速な解決策がなく、リフレクションの使用が必要になる可能性が高いことはわかっています。ここSOの誰かが以前にこれを行ったことがありますか?もしそうなら、あなたの洞察を共有していただけませんか?
答え
結局、リフレクションField
とModifier
クラスを使用してパスを見つけました。残念ながら、(会社のポリシーに反して) 私のコードを共有することはできませんが、私の出力をお見せすることはできます。クラス A は B のインスタンスを保持し、B は C のインスタンスを保持し、C は D のインスタンスを保持します。すべてSerializable
D を除きます。パスを見つけるために深さ優先検索を使用することになりました。
A.b ->
B.c ->
C.d instanceof class D
一時的にするC.d
と、検索で結果が得られません。かなりクール!