4

Java でのシリアライゼーションを研究していたときに、シリアライズ可能ではなく、クラス (インスタンス変数) で参照されているオブジェクトの状態を保存してシリアライズすることに遭遇しました。次のコードでは、クラス Collar(not serializable) への参照を持つクラス Dog (Serializable) を持っています。これは、クラス 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();
        }

    }
}

そして、次のエラーが発生しています:

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)

これは製品コードではありません。これは、練習と理解のためだけです。

4

2 に答える 2

2

readObjectとのストリームを閉じてはなりませんwriteObject。その場合、次の書き込み/読み取り試行は失敗します。

通常、ストリームは (他のリソースと同様に) 次のように処理する必要があります。

  • メソッドがストリームを所有している場合、つまり、メソッドがストリームを開いている場合は、同じメソッドでストリームを閉じます (通常、これはtry-with-resource ステートメントで行われます)。
  • メソッドがストリームを所有していない場合、つまり、他の場所から渡されたストリームを取得した場合 (通常はメソッドパラメーターを介して渡されます)、ストリームの所有者がストリームを使用して何をしたいのかがわからないため、ストリームを閉じないでください。メソッドが戻ります。
于 2013-11-14T07:10:41.283 に答える