Java对象序列化嵌套对象

Ami*_*kar 5 java serialization object

我正在研究 Java 中的序列化,当时我遇到了保存不可序列化且在要序列化的类(实例变量)中引用的对象的状态。在下面的代码中,我有类 Dog(可序列化),它引用了类 Collar(不可序列化);它又引用了 Color 类(不可序列化)。尽管尝试了所有可能性,我还是收到错误。这是我想出的最新代码:

class Color {
    private String colorName;

    public String getColorName() {
        return colorName;
    }

    public void setColorName(String colorName) {
        this.colorName = colorName;
    }

    Color(String color) {
        this.colorName = color;
    }
}

class Collar {

    private Color color;
    private int size;

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    Collar(int size, Color color) {
        this.size = size;
        this.color = color;
    }
}

class Dog implements Serializable {

    Dog(String breed, Collar collar) {
        this.breed = breed;
        this.collar = collar;
    }
    private String breed;

    public String getBreed() {
        return breed;
    }

    public void setBreed(String breed) {
        this.breed = breed;
    }

    public Collar getCollar() {
        return collar;
    }

    public void setCollar(Collar collar) {
        this.collar = collar;
    }
    transient private Collar collar;

    private void writeObject(ObjectOutputStream os) {
        try {
            os.defaultWriteObject();
            os.writeInt(this.getCollar().getSize());
            os.writeUTF(this.getCollar().getColor().getColorName());
            os.close();
        } catch (IOException ex) {
            Logger.getLogger(Dog.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void readObject(ObjectInputStream is) {
        try {
            is.defaultReadObject();
            int size = is.readInt();
            String colorName = is.readUTF();
            this.setCollar(new Collar(size, new Color(colorName)));
            is.close();
        } catch (Exception ex) {
            Logger.getLogger(Dog.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

public class App0001 {

    public static void main(String[] args) {

        try {
            Dog d = new Dog("Great Dane", new Collar(3, new Color("RED")));
            //System.out.println(d.getCollar().getColor().getColorName());
            ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("obj.ser"));
            os.writeObject(d);
            os.close();

            ObjectInputStream is = new ObjectInputStream(new FileInputStream("obj.ser"));
            d = (Dog) is.readObject();
            System.out.println(d.getCollar().getColor().getColorName());
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

java.io.IOException: Write error
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:260)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1847)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1756)
at java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1257)
at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1211)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1395)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:333)
at Serialization.App0001.main(App0001.java:121)
Run Code Online (Sandbox Code Playgroud)

这不是生产代码。这只是为了练习和理解。

isn*_*bad 2

您不能关闭readObject和中的流writeObject!如果这样做,下一次写入/读取尝试将失败。

通常,流(与其他资源一样)应按如下方式处理:

  • 如果您的方法拥有该流,即您的方法打开了它 - 用相同的方法关闭它(通常这是在语句中完成的try-with-resource
  • 如果您的方法不拥有该流,即它从其他地方传递的流(通常通过方法参数传递),请不要关闭它,因为您不知道该流的所有者在您执行此操作后想用它做什么方法返回。