当前位置: 首页 > 面试题库 >

如果两个对象引用指向同一个可序列化的对象,则在Java的序列化过程中会发生什么?

毋修为
2023-03-14
问题内容

如果两个对象引用指向同一个可序列化的对象,则在Java的序列化过程中会发生什么? 可序列化对象是否保存两次?
例如 :

    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<String,String> map1;
    private Map<String,String> 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实例。



 类似资料:
  • 问题内容: 我可能会尝试以困难的方式执行此操作,所以请让我知道是否有更好的解决方案。 我正在用Java开发一个简单的文字游戏,您可以通过GUI选择动作。我有几个班级正在尝试序列化一个是播放器,另一个是NPC。是否有一种简单的方法可以将一个以上的对象(播放器和NPC)序列化到同一文件中?我可以序列化一个对象并将其加载回游戏中。 我会以错误的方式处理吗?有没有更简单的方法来尝试保存游戏状态? 如果我有

  • 我正在试验Stanford CoreNLP库,我想序列化主要的StanfordCoreNLP管道对象,尽管它抛出了一个java.io.NotSerializableException。 完整故事:每当我运行我的实现时,将管道注释器和分类器加载到内存中大约需要15秒。最终进程的内存约为600MB(很容易小到可以存储在我的机箱中)。我想在第一次创建管道后保存它,这样我就可以在以后将其读入内存。 然而,

  • 问题内容: 你好亲爱的同事们, 我有一个Garden类,在其中我可以序列化和反序列化多个Plant类对象。如果想将其分配给mein静态方法中的调用变量,则可以进行序列化,但是不能进行反序列化。 反序列化代码: 我的调用代码: 编辑 我有一个空的Pointer异常 @NilsH的解决方案工作正常,谢谢! 问题答案: 如何序列化整个列表呢?无需序列化列表中的每个对象。 如果那不能解决您的问题,请发布有

  • 本文向大家介绍java对象的序列化和反序列化,包括了java对象的序列化和反序列化的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java对象的序列化和反序列化,供大家参考,具体内容如下 1. 什么是序列化        将对象转换为字节流保存起来,比如保存到文件里,并在以后还原这个对象,这种机制叫做对象序列化。(补充一句:把对象保存到永久存储设备上称为持久化) 2. 怎么实现序列化

  • 我正在做一个小组项目,我们遇到了一个软件序列化部分的问题。我们有类协议: 我们还有SearchResult类: 当我们通过客户端-服务器套接字连接编写协议类时,就会出现问题。问题是Protocol类中的TableModel对象在序列化/反序列化过程中的某个时刻变为null,而我们所做的任何事情都还没有解决这个问题。 到目前为止,我们已尝试: -在SearchResult中实现Serializabl

  • 我在序列化和反序列化同一JVM中的对象列表时遇到问题。确切地说,现在我的对象与对象具有相同的引用,它有以下规则: 现在在我的对象列表反序列化之后,在某个时候字母表引用不匹配。我用以下方法检查了一下: 得到了以下结果 现在看看VMId,既然它们是相同的,那么它不应该是相同的对象吗,就像上面的逻辑一样?谢谢你的帮助。