“没有有效的构造函数”序列化Path2D.Double的子类时 [英] "no valid constructor" when serializing a subclass of Path2D.Double

查看:143
本文介绍了“没有有效的构造函数”序列化Path2D.Double的子类时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试序列化Path2D.Double的子类,序列化有效,但是反序列化并不是因为以下异常:

I'm trying to serialize a subclass of Path2D.Double, the serialization works, but the deserialization doesn't because of the following Exception:

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本身也不能反序列化。

Could this be due to the superclass Path2D not implementing Serializable? But then, Path2D.Double itself couldn't be deserialized either.

这是我的代码:

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);
    }
}


推荐答案

I上周遇到了同样的问题,今天终于找到了答案。 Path2D对象将其构造函数声明为package-private。由于Java序列化要求第一个不可序列化的父类具有no-arg构造函数,并且无法访问,因此不在Path2D自己的程序包中的Path2D扩展名都不会反序列化。老实说,我认为这是Java方面的一种愚蠢,因为所有其他使用Float / Double子类的AWT抽象形状都将其默认构造函数声明为受保护的。

I ran into this same problem last week, finally found the answer today. The Path2D object declares its constructor as package-private. Since java serialization requires the first non-serializable parent class has a no-arg constructor, and it's not accessible, any extension of Path2D that is not in Path2D's own package will not deserialize. Honestly I think this is a flub on Java's side, since all the other AWT abstract shapes using Float/Double subclasses declare their default constructors as protected.

如果您好奇,通过查找 java.io.ObjectStreamClass.getSerializableConstructor(Class<?>)找到了根本原因。您会发现找到无法访问的构造函数时,它将返回null。

If you're curious, I found the root cause by tracing through java.io.ObjectStreamClass.getSerializableConstructor(Class<?>). You'll find that it returns null when it finds a constructor that is not accessible.

这篇关于“没有有效的构造函数”序列化Path2D.Double的子类时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆