反序列化对象与原始对象的实例相同 [英] Is a deserialised object the same instance as the original

查看:156
本文介绍了反序列化对象与原始对象的实例相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我从类中实例化一个对象时,一个对象被保存在java堆中。当我通过序列化保存对象并稍后反序列化对象时,我是否正确理解该对象现在将具有新的堆地址但仍将是该类的EXACT SAME实例。

When I instantiate an object from a class, an object is saved in the java heap. When I save the object by serializing it and I later deserialize the object, do I understand correctly that the object will now have a new heap address but will still be the EXACT SAME instance of the class.

推荐答案

你的问题的答案不能只是肯定或否定。要分析这个概念。我建议你拿一支铅笔和纸,自己记住以下几点。

The answer to your question cannot be just a yes or no. To analyze the concept is required. I will suggest you to take a pencil and paper and do it yourself keeping the below points in mind.


  • 所有java对象都是用java创建的堆(除了一些保存在池中的
    ,但对于你的问题,我们现在将跳过它们)。

  • 当使用new关键字创建类的实例时,
    反序列化,克隆方法或反射api的newInstance方法,
    a堆中的新空间被保留,我们将它分配给对象引用
    (引用可以是对象的类或超级$之一b $ b对象类的类 - 我们现在可以忽略
    的这个细节了。)

  • 当你保存对象时,对象的状态会被保存,所有的都是
    嵌套对象。

  • 当您对对象进行反序列化时,该对象将在堆中创建一个新条目
    ,该条目不会引用任何对象。

  • All java objects are created in java heap (except for some which are kept in pool but for you question we will skip them for now).
  • When an instance of a class is created using new keyword, deserialization, clone method or reflection api's newInstance method, a new space in heap is reserved and we assign it to a object reference (the reference can be of the object's class or one of the super classes of the object's class - again we can ignore this detail for now).
  • When you save your object, the object's state is saved with all it's nested objects.
  • When you deserialize your object, the object will create a new entry in heap which will not have any references to any of the objects.

请查看下图,了解上述概念你的背景:

Look at the below diagram for picturizing the above concept in you context:

所有对象A引用都指向一个堆条目,如果尝试objectB.getObjectA()== objectC.getObjectA()或任何其他此类操作,您将获得true 。

All the object A references are pointing to one heap entry and if you try objectB.getObjectA() == objectC.getObjectA() or any other such operation, you will get true.

案例1 当您单独保存对象并反序列化它们时,堆中会发生什么:

Case 1 When you save the objects separately and deserialize them here is what happens in the heap:

你现在可以弄清楚,objectBcopy.getObjectA()== objectCcopy.getObjectA()不会返回true,因为复制对象的对象A的引用不再相同。

As you can figure out now that objectBcopy.getObjectA() == objectCcopy.getObjectA() will not return true as the references of object A for the copied objects are no more same.

案例2 相反,当您将对象保存在单个文件中并稍后对其进行反序列化时,堆中会发生以下情况:

Case 2 On the contrary, when you save the objects in a single file and deserialize them later, here is what happens in the heap:

正如你现在可以弄清楚的那样,objectBcopy.getObjectA()== objectCcopy.getObjectA()现在将为true,因为对象A副本的引用是相同的,但那仍然是对象的新副本A。

As you can figure out now that objectBcopy.getObjectA() == objectCcopy.getObjectA() will now be true as the references of object A copy are same, but that's still a new copy of object A.

支持扣除的快速计划(案例1和案例2):

A quick program to support my deductions (Case 1 and Case 2):

public class Test{

    public static void main (String args[]) throws IOException, ClassNotFoundException{
        A a = new A();

        B b = new B();
        b.a = a;

        C c = new C();
        c.a = a;

        System.out.println("b.a == c.a is " + (b.a == c.a));

        // Case 1 - when two diferent files are used to write the objects
        FileOutputStream fout = new FileOutputStream("c:\\b.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fout);
        oos.writeObject(b);
        oos.close();
        fout.close();

        fout = new FileOutputStream("c:\\c.ser");
        oos = new ObjectOutputStream(fout);
        oos.writeObject(c);
        oos.close();
        fout.close();

        FileInputStream fileIn = new FileInputStream("c:\\b.ser");
        ObjectInputStream in = new ObjectInputStream(fileIn);
        B bCopy = (B) in.readObject();
        in.close();
        fileIn.close();

        fileIn = new FileInputStream("c:\\c.ser");
        in = new ObjectInputStream(fileIn);
        C cCopy = (C) in.readObject();
        in.close();
        fileIn.close();
        System.out.println("Case 1 - bCopy.a == cCopy.a is " + (bCopy.a == cCopy.a));

        // Case 2 - when both the objects are saved in the same file
        fout = new FileOutputStream("c:\\both.ser");
        oos = new ObjectOutputStream(fout);
        oos.writeObject(b);
        oos.writeObject(c);
        oos.close();
        fout.close();


        fileIn = new FileInputStream("c:\\both.ser");
        in = new ObjectInputStream(fileIn);
        bCopy = (B) in.readObject();
        cCopy = (C) in.readObject();
        in.close();
        fileIn.close();
        System.out.println("Case 2 - bCopy.a == cCopy.a is " + (bCopy.a == cCopy.a));
    }
}

class A implements Serializable{

}

class B implements Serializable{
    A a;
}

class C implements Serializable{
    A a;
}

使用以下输出:

 b.a == c.a is true
 Case 1 - bCopy.a == cCopy.a is false
 Case 2 - bCopy.a == cCopy.a is true

这篇关于反序列化对象与原始对象的实例相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆