0

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)

これは、スーパークラス Path2D が Serializable を実装していないことが原因でしょうか? しかし、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);
    }
}
4

1 に答える 1

4

私は先週この同じ問題に遭遇し、今日ついに答えを見つけました。Path2D オブジェクトは、そのコンストラクターを package-private として宣言します。Java シリアライゼーションでは、最初のシリアライズ不可能な親クラスに引数のないコンストラクターが必要であり、アクセスできないため、Path2D 自身のパッケージに含まれていない Path2D の拡張はデシリアライズされません。Float/Double サブクラスを使用する他のすべての AWT 抽象形状は、デフォルトのコンストラクターを保護されていると宣言しているため、正直なところ、これは Java 側の失敗だと思います。

興味がある方は、 をたどって根本的な原因を見つけましたjava.io.ObjectStreamClass.getSerializableConstructor(Class<?>)。アクセスできないコンストラクターが見つかると、null が返されることがわかります。

于 2012-10-08T19:11:40.453 に答える