反序列化对象与原始对象的实例相同 [英] Is a deserialised object the same instance as the original
问题描述
当我从类中实例化一个对象时,一个对象被保存在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屋!