2

How are the values of static variables persisted during serialization(If at all persisted). I have read similar questions on stack where it says that static variables are inherently transient i.e their state or current values is not serialized.

I was just doing a very simple example where i serialized a class and saved it to a file and then again reconstructed the class from the file.Surprisingly I find that the value of the static variable at and when the serialization happened is saved.

How does this happen. Is this because the class template along with it's instance information is saved during serialization. Here is the code snippet -

public class ChildClass implements Serializable, Cloneable{

    /**
     * 
     */
    private static final long serialVersionUID = 5041762167843978459L;

    private static int staticState;
    int state = 0;

    public ChildClass(int state){
        this.state = state;
        staticState = 10001;
    }

    public String toString() {
        return "state" + state + " " + "static state " + staticState;
    }

    public static void setStaticState(int state) {
        staticState = state;
    }

and here is my main class

public class TestRunner {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new TestRunner().run();
    }

    public TestRunner() {

    }

    public void run() {
        ChildClass c = new ChildClass(101);
        ChildClass.setStaticState(999999);
        FileOutputStream fo = null;
        ObjectOutputStream os = null;

        File file = new File("F:\\test");
        try {
            fo = new FileOutputStream(file);
            os = new ObjectOutputStream(fo);
            os.writeObject(c);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

            try {
                if(null != os)os.close();
                if(null != fo) fo.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }


        FileInputStream fi = null;
        ObjectInputStream ois = null;
        ChildClass streamed;

        try {
            fi = new FileInputStream(file);
            ois = new ObjectInputStream(fi);
            Object o = ois.readObject();
            if(o instanceof ChildClass){
                streamed = (ChildClass)o;
                //ChildClass cloned = streamed.clone();
                System.out.println(streamed.toString());
            }
        } catch (IOException | ClassNotFoundException  e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                if(null != ois)ois.close();
                if(null != fi) fi.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }

Note : There is nothing wrong with the code. I just am wondering how the value of the static variable 'staticState' in the class 'ChildClass' gets saved. Will the state be saved if i transmit this serialized data over a network then

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Dibzmania
  • 1,934
  • 1
  • 15
  • 32
  • 1
    Possible duplicate of [this question](http://stackoverflow.com/questions/3147811/serialize-static-attributes-in-java). I did not "dupe-hammer" the question, as I'm not yet fully sure if this is a proper duplicate or not. – Hovercraft Full Of Eels Nov 16 '14 at 16:12
  • Although my question is related to serialization of static variable but my question is on a behavior I am noticing that actually is not as per standard documentation. – Dibzmania Nov 16 '14 at 16:24

1 Answers1

2

The static field value was not serialized. The output is printing the new value of the static field simply because you modified it to 999999 but you never reset its value to the old one before de-serizalizing. Since the field is static, the new value is reflected in any instance of ChildClass.

To properly assert that the field is not serialized, reset the value to 10001 before de-serializing the object, and you will notice that its value is not 999999.

...
ChildClass.setStaticState(10001);

FileInputStream fi = null;
ObjectInputStream ois = null;
ChildClass streamed;

...
// when de-serializing, the below will print "state101 static state 10001"
System.out.println(streamed.toString());
M A
  • 71,713
  • 13
  • 134
  • 174
  • That's what my question is. Is the change in value for the static variable reflected because I am serializing and de-serializing within the same program i.e the class is already loaded within the VM. In case the serialized data is sent over network will it reset to the value set in constructor?? – Dibzmania Nov 16 '14 at 16:23
  • @Dibzmania Yes it will reset to the old one. Indeed the new value here is because the class is already in loaded in the VM. – M A Nov 16 '14 at 16:24
  • I will go with your confirmation :-) – Dibzmania Nov 16 '14 at 16:27
  • @Dibzmania Just a small correction on my side: actually to be precise, when you de-serialize an object, the value of the static field would be zero in this case, not 10001 (i.e. the value in the constructor). – M A Nov 16 '14 at 16:29