2012-03-27 5 views
2

DirectedSparseGraphは直列化可能(javadoc)を実装しているので、グラフを作成せずにファイルにシリアル化してから逆シリアル化することはできますか? deserializer.readObject()が呼び出され、「有効なコンストラクターがありません」というメッセージとともに「InvalidClassException」がスローされます。JUNGのDirectedSparseGraphはシリアル化可能ですか?

javadocとソースファイルを見ると、引数なしのコンストラクタがあります。

これはライブラリのバグですか?または私は何かを逃している? Javaはどのタイプのコンストラクタを期待していますか?

DirectedSparseGraph graph = new DirectedSparseGraph(); 

    FileOutputStream underlyingStream = new FileOutputStream("output/temp.jung"); 
    ObjectOutputStream serializer = new ObjectOutputStream(underlyingStream); 
    serializer.writeObject(graph); 
    serializer.close(); 
    underlyingStream.close(); 

    FileInputStream underlyingStream2 = new FileInputStream("output/temp.jung"); 
    ObjectInputStream deserializer = new ObjectInputStream(underlyingStream2); 
    DirectedSparseGraph loadedGraph = (DirectedSparseGraph) deserializer.readObject(); //EXCEPTION THROWN HERE 
    deserializer.close(); 
    underlyingStream2.close(); 

例外:

Exception in thread "main" java.io.InvalidClassException: edu.uci.ics.jung.graph.DirectedSparseGraph; edu.uci.ics.jung.graph.DirectedSparseGraph; no valid constructor 
at java.io.ObjectStreamClass.checkDeserialize(Unknown Source) 
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
at java.io.ObjectInputStream.readObject0(Unknown Source) 
at java.io.ObjectInputStream.readObject(Unknown Source) 
at gui.GraphViewer.main(GraphViewer.java:39) 
Caused by: java.io.InvalidClassException: edu.uci.ics.jung.graph.DirectedSparseGraph; no valid constructor 
at java.io.ObjectStreamClass.<init>(Unknown Source) 
at java.io.ObjectStreamClass.lookup(Unknown Source) 
at java.io.ObjectOutputStream.writeObject0(Unknown Source) 
at java.io.ObjectOutputStream.writeObject(Unknown Source) 
at gui.GraphViewer.main(GraphViewer.java:33) 
+0

頂点を保存してファイルに保持し、後でそのファイルから最後の状態にロードしますか? 「jung-samples-2.0.1.jar」( 'jung-samples-2.0.1-sources.jar'を使用)の' PersistentLayoutDemo.java'を確認してください。 'PersistentLayoutImpl.persist()'メソッドは 'PersistentLayout.persist()'インタフェースメソッドを実装し、直列化された 'Point'クラスを使って頂点を保存します。 –

答えて

1

シリアル化を実装するクラスのコンストラクタの唯一の要件は、その 継承階層内の最初の非直列化可能スーパークラスが引数なしを持っていてはいけないということですコンストラクタ

ソース:http://www.jguru.com/faq/view.jsp?EID=251942

非直列化可能クラスのフィールドは、 クラスのpublicまたはprotected no-argコンストラクタを使用して、 に初期化されます。引数のないコンストラクタは、サブクラス( シリアライズ可能)にアクセス可能でなければなりません。直列化可能なサブクラスのフィールドは、ストリームから復元されます 。

出典:http://docs.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html

+0

それが拡張するクラスに引数のないコンストラクタがない場合、それを直列化することは不可能ですか?その場合、なぜシリアライザブルを実装するのが面倒なのでしょうか?これは図書館の間違いですか? – Crashthatch

+2

スーパークラスが必要なコンストラクタを持っていたときに、シリアライズ可能になっている可能性があります。 [* Item 74:Serializableをうまく実装*](http://java.sun.com/docs/books/effective/)も参照してください。 – trashgod

0

私はXStream libraryを使用してDirectedSparseGraphをシリアル化。 オブジェクトがSerializableを実装していない場合でも、2行のコードでオブジェクトをシリアル化およびシリアル化解除します。これは、サードパーティのオブジェクトをシリアル化する際に特に便利です。シリアル化できるように変更することはできません。

これを試してみると、ネイティブJavaのシリアル化に戻ってくることはありません。 唯一の問題は、XStreamがXMLにシリアル化されることです。厳しいパフォーマンス要件がある場合は、それが最良の選択ではありません。

関連する問題