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.
Serialization is a mechanism of converting the state of an object into a byte stream. Deserialization is the reverse process where the byte stream is used to recreate the actual Java object in memory. This mechanism is used to persist the object.
Deserialization is the process of reconstructing a data structure or object from a series of bytes or a string in order to instantiate the object for consumption. This is the reverse process of serialization, i.e., converting a data structure or object into a series of bytes for storage or transmission across devices.
Deserialization is the opposing process which takes data from a file, stream or network and rebuilds it into an object. Serialized objects can be structured in text such as JSON, XML or YAML. Serialization and deserialization are safe, common processes in web applications.
To serialize an object means to convert its state to a byte stream so way that the byte stream can be reverted back into a copy of the object. A Java object is serializable if its class or any of its superclasses implements either the java. io. Serializable interface or its subinterface, java.
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.
Look at the below diagram for picturizing the above concept in you context:
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.
Case 1 When you save the objects separately and deserialize them here is what happens in the heap:
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.
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:
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.
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; }
With the following output:
b.a == c.a is true Case 1 - bCopy.a == cCopy.a is false Case 2 - bCopy.a == cCopy.a is true
Before serializing:
A originalA = ...; B.a == C.a == D.a == E.a == originalA
All B.a
, C.a
, D.a
and E.a
point to the same reference of A
, originalA
.
After serializing and deserializing:
A otherA = ...; B.a == C.a == D.a == E.a == otherA
All B.a
, C.a
, D.a
and E.a
point to the same reference of A
, otherA
.
However:
originalA != otherA
though
originalA.equals(otherA) == true
Note: equals()
will return true
only if it is overriden to consistently check equality based on serialized fields. Otherwise, it might return false
.
EDIT:
Proof:
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class Sample { static class A implements Serializable { private static final long serialVersionUID = 1L; } static class B implements Serializable { private static final long serialVersionUID = 1L; A a; } static class C implements Serializable { private static final long serialVersionUID = 1L; A a; } public static void main(String args[]) throws IOException, ClassNotFoundException { A originalA = new A(); B b = new B(); b.a = originalA; C c = new C(); c.a = originalA; System.out.println("b.a == c.a is " + (b.a == c.a)); FileOutputStream fout = new FileOutputStream("ser"); ObjectOutputStream oos = new ObjectOutputStream(fout); oos.writeObject(b); oos.writeObject(c); oos.close(); fout.close(); FileInputStream fileIn = new FileInputStream("ser"); ObjectInputStream in = new ObjectInputStream(fileIn); B bDeserialized = (B) in.readObject(); C cDeserialized = (C) in.readObject(); in.close(); fileIn.close(); System.out.println("bDeserialized.a == cDeserialized.a is " + (bDeserialized.a == cDeserialized.a)); } }
The deserialized instance will definitely be a distinct instance from the original, as in deserialized != original
will always be true.
The deserialized instance may or may not be equal to the original instance, as in deserialized.equals(original)
. For a reasonable implementation of a Serializable
class, equals
probably will be true after deserialization, but it is trivial to create a class for which this does not hold:
class Pathological implements Serializable {
transient int value;
Pathological(int value) { this.value = value; }
@Override public int hashCode() { return value; }
@Override public boolean equals(Object other) {
if (other == this) { return true; }
if (other instanceof Pathological) {
return ((Pathological) other).value == this.value;
}
return false;
}
}
Unless you happen to pass zero when constructing the Pathological
, the instances won't be equal after serialization/deserialization, since the value of value
won't be serialized (as it is transient).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With