如果两个对象引用指向同一个可序列化的对象,那么在java中序列化期间会发生什么?

如果两个对象引用指向同一个可序列化的对象,那么在java中序列化期间会发生什么? Serializable对象是否会保存两次?
例如 :

class King implements java.io.Serializable { private String name="Akbar"; } class Kingdom implements java.io.Serializable { King goodKing=new King(); King badKing=goodKing; } public class TestSerialization { public static void serializeObject(String outputFileName, Object serializableObject) throws IOException { FileOutputStream fileStream=new FileOutputStream(outputFileName); ObjectOutputStream outStream=new ObjectOutputStream(fileStream); outStream.writeObject(serializableObject); outStream.close(); } public static void main(String[] args) { Kingdom kingdom=new Kingdom(); try { TestSerialization.serializeObject("Kingdom1.out", kingdom); }catch(IOException ex) { ex.getMessage(); } } } 

现在,是否只为goodKingbadKing参考保存了一个对象状态,或者King对象被保存了两次?

ObjectOutputStream的文档说明会发生什么:

对象的默认序列化机制会写入对象的类,类签名以及所有非瞬态和非静态字段的值。 对其他对象的引用(瞬态或静态字段除外)也会导致这些对象被写入。 使用引用共享机制对对单个对象的多个引用进行编码,以便可以将对象的图形恢复为与写入原始图像时相同的形状。

(我的重点)

例如,如果您对单个对象有多个引用,则在重构图形时,最终会对该对象的单个重构版本进行多次引用,而不是对其的多个等效实例的引用。

当然,如果被序列化的容器实现了不同的机制,则该行为由该机制决定,而不是默认机制。

例如,如果我们有ThingTest

Thing.java

 import java.io.*; import java.util.*; public class Thing implements Serializable { private Map map1; private Map map2; public Thing() { this.map1 = new HashMap(); this.map2 = this.map1; // Referring to same object } public void put(String key, String value) { this.map1.put(key, value); } public boolean mapsAreSameObject() { return this.map1 == this.map2; } } 

Test.java

 import java.io.*; public class Test implements Serializable { public static final void main(String[] args) { try { // Create a Thing Thing t = new Thing(); t.put("foo", "bar"); // Write it out ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("foo")); os.writeObject(t); os.close(); os = null; // Read it in Thing t2; ObjectInputStream is = new ObjectInputStream(new FileInputStream("foo")); t2 = (Thing)is.readObject(); is.close(); is = null; // Same underlying map for both properties? System.out.println("t2.mapsAreSameObject? " + t2.mapsAreSameObject()); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } } } 

并运行java Test ,我们得到:

  t2.mapsAreSameObject? 真正 

…因为Thing的成员, map1map2最终都指向一个HashMap实例。