Difference of static deserialization in Java depending on when serialize the object

mrbela :

I am trying to figure out the (de/)serialization in Java.

I have read, that static variables are not serialized.

To figure this out, I've made a little example:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SerialDemo {

    private static void writeFile() throws IOException, ClassNotFoundException {
        ObjectOutputStream o=new ObjectOutputStream(new FileOutputStream("foo"));
        Test test = new Test();
        o.writeObject(test);
        o.flush();
    }

    private static Test readFile() throws FileNotFoundException, IOException, ClassNotFoundException {
        ObjectInputStream in=new ObjectInputStream(new FileInputStream("foo"));
        return (Test) in.readObject();
    }
}
class Test implements Serializable{
    static Integer i;
    public Test(){
        i = 10;
    }
}

Why are there differences between the run of those two main-methods?

First version: Serialize and deserialize in a single run

public static void main(String[] args)  {

        try {
            // Serialization
            writeFile();
            // Deserialization
            Test deserializedFile = readFile();
            System.out.println(deserializedFile.i);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

This outputs 10. But why? I thought the value of Integer i was not serialized, since it is static.

Second version: Serialize and deserialize in two different runs.

If I first run:

public static void main(String[] args)  {
        try {
            // Serialization
            writeFile();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

And in a second run:

public static void main(String[] args)  {
        try {
            // Deserialization
            Test deserializedFile = readFile();
            System.out.println(deserializedFile.i);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

It outputs null, as I suggested in first version too.

Where is the difference?!

GhostCat salutes Monica C. :

Simple: it is a static variable. It gets initialized in your first example, when you create one instance using the constructor!

In the second example, that constructor is never called, the field stays null!

That is all there is to this. And as you said yourself: the static field is not written into that file. The only thing that matters in your two examples is that one version calls the constructor, and the other does not.

Beyond that, there is another misconception here: you write deserializedFile.i... That is conceptually wrong. You should use Test.i instead. Static variables are the same for all instances, their owning scope is the Test class, not some instance of that class!

And just for the record: deserializedFile is a very misleading name. That variable represents a deserialized Test object. It is not to a file! Names should say what they are about and not lie. This names lies big time!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=128924&siteId=1