-2

我正在进行序列化,但我无法理解以下内容:

我不明白为什么这段代码的输出是:

import java.io.*;

public class InnerOuterTest {
    public static ObjectOutputStream out;
    public static ObjectInputStream in;

    static {
        try {
            out = new ObjectOutputStream(new FileOutputStream("save.ser"));
            in = new ObjectInputStream(new FileInputStream("save.ser"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        try {
            ShouldForgive f = new ShouldForgive();
            f.x = 5;
            write(f);
            ShouldForgive g = read();
            System.out.println(g.x);
            f.x = 0;
            g.x=8;
            write(f);
            ShouldForgive v = read();
            System.out.println("is "+v.x);
        } finally {
            out.close();
            in.close();
        }
    }

    private static void write(ShouldForgive f) throws IOException {
        out.writeObject(f);
    }

    public static ShouldForgive read() throws ClassNotFoundException, IOException {
        return (ShouldForgive) in.readObject();
    }
}

class ShouldForgive implements Serializable {
    int x = -1;
}

5
8

并不是

5
0

我尝试f == g了返回false,如果我重置输入流。我发现如果我实现readObject它只会被调用一次......我不明白这种行为。(为什么对象只读取一次?)

我觉得序列化只发生一次......对象是如何跟踪的?即使我实现readObject并且writeObject没有从文件中实际读取或写入,我仍然得到8

4

2 回答 2

2

如果您out.reset()在第一次写入后调用,您将获得您期望的行为,或者如果您使用writeUnshared()而不是writeObject(). 已经写入流的对象不会被重写;而是写入先前写入的对象的“句柄”。有关详细信息,请参阅 Javadoc。

于 2012-06-30T01:57:38.353 回答
-1

好吧……我想我明白了……

  1. 在序列化期间,它不是被序列化的对象,而是它的实例变量......作为提取和存储。对于一个对象,它的实例变量就是一切......

  2. 因此,在反序列化过程中,相同的实例变量会膨胀回来,并使用这些实例变量值,在堆上创建另一个相同的对象。

  3. 如果您检查这两个对象的哈希码,它们将是不同的。

那就是导致您提到的上述行为。

要么按照这个顺序

f.x = 0;
g.x=8;

或这个

g.x=8;       
f.x = 0; 

结果仍然是 8,因为它现在是堆上完全不同的对象,具有不同的实例变量。

编辑部分

The below code will print f as 5..... for both the sysout

public static void main(String[] args) throws IOException, ClassNotFoundException {
        try {
            ShouldForgive f = new ShouldForgive();
            f.x = 5;
            write(f);
            ShouldForgive g = read();
            System.out.println(g.x);

            f.x=0;
            write(f);
            ShouldForgive v = read();
            System.out.println("is "+v.x);
        } finally {
            out.close();
            in.close();
        }
    }
于 2012-06-29T15:48:41.643 回答