Is a deserialised object the same instance as the original

前端 未结 5 1879
心在旅途
心在旅途 2021-02-04 02:07

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 corr

5条回答
  •  礼貌的吻别
    2021-02-04 02:13

    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.

    • 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:

    enter image description here

    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:

    enter image description here

    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:

    enter image description here

    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
    

提交回复
热议问题