我写了以下简单的代码
public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException
{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("data.txt")));
Human human = new Human();
human.setAge(21);
human.setName("Test");
System.out.println("Human : " + human);
oos.writeObject(human);
human.setName("Test123");
oos.writeObject(human);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("data.txt")));
Human newHuman1 = (Human)ois.readObject();
System.out.println("newHuman1 :" + newHuman1);
Human newHuman2 = (Human)ois.readObject();
System.out.println("newHuman2 :" + newHuman2);
}
它打印 –
Human : Human [age=21, name=Test]
newHuman1 :Human [age=21, name=Test]
newHuman2 :Human [age=21, name=Test]
我无法理解为什么它不打印
newHuman2 :Human [age=21, name=Test123]
为什么更改实例状态不会反映在序列化对象中?
解决方法:
你已经把对象写了两次,但只读回了第一个.因此,如果写入了两个对象副本,则需要添加第二个读取以查看第二个副本.在从文件读取之前关闭输出可能是个好主意,以确保刷新缓冲区.
但所有这一切:ObjectOutputStream只写一个给定的对象,然后对同一个对象的后续写入写入对它的引用,而不是它的第二个副本.从the documentation开始:
The default serialization mechanism for an object writes the class of the object, the class signature, and the values of all non-transient and non-static fields. References to other objects (except in transient or static fields) cause those objects to be written also. Multiple references to a single object are encoded using a reference sharing mechanism so that graphs of objects can be restored to the same shape as when the original was written.
我们的想法是,您将同时序列化对象图.在序列化期间改变对象图是一件非常奇怪的事情.我找不到任何文档说它不受支持,但是在项目中添加第二个读取仍然显示“Test”而不是“Test123”,所以…
要写出两个单独的Human对象,您需要在编写之前创建第二个:
import java.io.*;
public class Human implements Serializable {
private int age;
private String name;
public void setAge(int a) {
this.age = a;
}
public void setName(String n) {
this.name = n;
}
public String toString() {
return "[Human " + this.age + ", " + this.name + "]";
}
public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException
{
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("data.txt"))))
{
Human human = new Human();
human.setAge(21);
human.setName("Test");
System.out.println("Human : " + human);
oos.writeObject(human);
human = new Human(); // <== Change
human.setAge(21); // <== Change
human.setName("Test123");
oos.writeObject(human);
}
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("data.txt"))))
{
Human newHuman = (Human)ois.readObject();
System.out.println("newHuman1 :" + newHuman);
newHuman = (Human)ois.readObject();
System.out.println("newHuman2 :" + newHuman);
}
}
}
如果上面没有标记这些行,则第二次写入只会导致对第一个对象的引用.我们可以证明这样:
public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException
{
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("data.txt"))))
{
Human human = new Human();
human.setAge(21);
human.setName("Test");
System.out.println("Human : " + human);
oos.writeObject(human);
human.setName("Test123");
oos.writeObject(human);
}
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("data.txt"))))
{
Human newHuman1 = (Human)ois.readObject();
System.out.println("newHuman1 :" + newHuman1);
Human newHuman2 = (Human)ois.readObject();
System.out.println("newHuman2 :" + newHuman2);
System.out.println("Same object? " + (newHuman1 == newHuman2));
}
}
……哪个输出:
Human : [Human 21, Test] newHuman1 :[Human 21, Test] newHuman2 :[Human 21, Test] Same object? true