How serialization works when only subclass implements serializable
Asked Answered
R

3

27

Only subclass has implemented Serializable interface.

import java.io.*;

public class NewClass1{

    private int i;
    NewClass1(){
    i=10;
    }
    int getVal() {
        return i;
    }
    void setVal(int i) {
        this.i=i;
    }
}

class MyClass extends NewClass1 implements Serializable{

    private String s;
    private NewClass1 n;

    MyClass(String s) {
        this.s = s;
        setVal(20);
    }

    public String toString() {
        return s + " " + getVal();
    }

    public static void main(String args[]) {
        MyClass m = new MyClass("Serial");
        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serial.txt"));
            oos.writeObject(m); //writing current state
            oos.flush();
            oos.close();
            System.out.print(m); // display current state object value
        } catch (IOException e) {
            System.out.print(e);
        }
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("serial.txt"));
            MyClass o = (MyClass) ois.readObject(); // reading saved object
            ois.close();
            System.out.print(o); // display saved object state
        } catch (Exception e) {
            System.out.print(e);
        }
    }
}

One thing, which I noticed here is, parent class is not serialized. Then, why didn't it throw NotSerializableException indeed it is showing following

Output

Serial 20
Serial 10

Also, output differ from Serialization and De-serialization. I just only know, it is because of parent class has not implemented Serializable. But, If anyone explain me, what happens during object serialization and de-serialization. How it changes the value ? I'm not able to figure out, also I have used comment in my program. So, if I'm wrong at any point, please let me know.

Ruthenious answered 26/12, 2012 at 15:2 Comment(0)
J
36

according to the Serializable javadoc

During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.

also, serialization exception is only thrown if the class being serialized is not serializable. having non-serializable parents is fine (as long as they have a no-arg constructor). Object itself isnt Serializable, and everything extends it. the quote above also explains why you get different values for the value field - the no-arg constructor for the parent class is set, which sets the value field to 10 - the field belongs to the (non-serializable) parent so its value isnt written to/read from the stream.

Justinajustine answered 26/12, 2012 at 15:11 Comment(0)
E
6

If your MyClass holds reference to an object of non serializable class you will get NotSerializable exception at run time. To test, modify MyClass so that it holds a reference to an object of NewClass1. If you run again it will throw an exception.

Deserialization is essentially creating an instance of a serializable class and restoring its properties. During this process the constructor of the serializable class is not called. Rather the no arg constructor of first non serializable super class is called.

In your case the no arg constructor of NewClass1 assigns 10 to its instance variable i. So, during deserialization it's printing 10 instead of 20.

Exsect answered 26/12, 2012 at 15:12 Comment(4)
yes , it will. That is why, my question wasn't that. I have changed the code from the original one. Please go through my code.Ruthenious
My question is not exactly, why my code is not showing NotSerializableException?? rather I'm asking, how these output differ, background of serialization and deserialization in current code.Ruthenious
Added some more info to my answer. Hope it helps you.Exsect
You get exception Bcz over serialised class i.e having state , how can member create with default constructor? It will trow exception NotSerializableExceptionHawkinson
A
0

I've not tested it, but you shall get a NotSerializableException if serializing the instance of base class. It is the same when your class contains some members that are not Serializable.

Means if you create an object NewClass1 nc1 = new NewClass1(); and try to serialize the obj nc1, you will get the exception that you want.

Alliterate answered 26/12, 2012 at 15:9 Comment(2)
Yes, in this scenario, i'm getting NotSerializableException, but not in current scenario. Please go through my code.Ruthenious
Hmmm... I understand what are you trying to dig. Your current scenario works because you have a default constructor in the base class. JVM is little intelligent in this case and just neglects the int present in base class. While deserializing it calls the default constructor. If you add a pram to the constructor of the base class, still the object will be serailized, but I guess you will get an exception while deserializing.Alliterate

© 2022 - 2024 — McMap. All rights reserved.