2012-05-06 10 views
0

のサブクラスを直列化するとき、私は直列化作品、はPath2D.Doubleのサブクラスを直列化しようとしているが、直列化復元は、次の理由の例外でない:「有効なコンストラクタ」はPath2D.Double

Exception in thread "main" java.io.InvalidClassException: CustomShape; no valid constructor 
at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.java:147) 
at java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:755) 
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347) 
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369) 
at CustomShape.main(CustomShape.java:38) 

これは、Serializableを実装していないスーパークラスPath2Dが原因である可能性がありますか?しかし、その後、Path2D.Double自体もデシリアライズできませんでした。

はここに私のコードです:

import java.awt.geom.Path2D; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 

public class CustomShape extends Path2D.Double { 
    private static final long serialVersionUID = 1L; 

    public CustomShape() { 
     super(); 
    } 

    public static void main(String[] args) throws Exception { 
     //Make Shape 
     //Path2D shape = new Path2D.Double(); //works 
     Path2D shape = new CustomShape(); //doesn't work 
     shape.moveTo(0, 0); 
     shape.lineTo(0, 10); 
     shape.lineTo(10, 10); 
     shape.lineTo(10, 0); 
     shape.closePath(); 

     File file = new File(System.getProperty("user.dir"), "shape"); 
     //Save Shape 
     if (!file.exists()) { 
      file.createNewFile(); 
     } 
     ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file)); 
     out.writeObject(shape); 
     out.flush(); 
     out.close(); 

     //Load Shape 
     ObjectInputStream in = new ObjectInputStream(new FileInputStream(file)); 
     Object obj = in.readObject(); 
     in.close(); 

     System.out.println(obj); 
    } 
} 
+0

Path2Dとその内部クラスDoubleの宣言を表示します。 –

+0

@Marko Topolnik彼らはjreクラスです。 'java.awt.geom.Path2D'は' private'' readObject'と 'writeObject'の実装を持っています。パッケージプライベート 'transient double [] doublecode 'を扱うようです。 – esej

+0

申し訳ありませんが、インポートは見られませんでした。私はコードを見て、問題の原因を見ることができません。 –

答えて

4

私は先週、この同じ問題に遭遇し、最終的には今日の答えを見つけました。 Path2Dオブジェクトは、そのコンストラクタをpackage-privateとして宣言します。 java直列化には最初の直列化不可能な親クラスには引数なしのコンストラクタがあり、アクセスできないので、Path2D自身のパッケージにないPath2Dの拡張は逆シリアル化されません。正直なところ、これは、Javaの面白さです.Float/Doubleサブクラスを使用する他のすべてのAWT抽象図形は、デフォルトのコンストラクタをprotectedとして宣言しているためです。

あなたは好奇心旺盛であれば、私はjava.io.ObjectStreamClass.getSerializableConstructor(Class<?>)てトレースすることにより、根本的な原因を発見しました。アクセスできないコンストラクタが見つかるとnullを返すことがわかります。

関連する問題