Are static variables serialized in Serialization process
Asked Answered
M

9

42

I'm stumbled upon understanding java serialization. I have read in many documents and books that static and transient variables cannot be serialized in Java. We declare a serialVersionUid as follows.

private static final long serialVersionUID = 1L;

If a static variable was not serialized then, we often face an exception during the de-serialization process.

java.io.InvalidClassException

in which the serialVersionUID from the deserialized object is extracted and compared with the serialVersionUID of the loaded class.

To my knowledge i think that if static variables cannot be serialized. There is no point of that exception. I may be wrong because I'm still learning.

Is it a myth that "Static and transient variables in java cannot be serialized". Please correct me, I'm in a mess about this concept.

Mercie answered 12/6, 2012 at 16:39 Comment(0)
S
55

serialVersionUID is a special static variable used by the serialization and deserialization process, to verify that a local class is compatible with the class used to serialize an object. It's not just a static variable as others, which are definitely not serialized.

When an object of a class is first serialized, a class descriptor containing among other things the class name and serial version UID is written to the stream. When this is deserialized, the JVM checks if the serial version UID read from the stream is the same as the one of the local class. If they're not, it doesn't even try to deserialize the object, because it knows the classes are incompatible.

Stewart answered 12/6, 2012 at 16:45 Comment(5)
What does the term special static variable mean ?Mercie
It means that it's a static variable that's special. (Specifically, it's treated differently from other static variables in serialization.)Sol
It's special, because the serialization mechanism looks for this static variable to know what the serial version UID of the class is. All the other static variables are just ignored by the serialization mechanism.Stewart
Thanks for the precise answer, appreciate it.Mercie
Static variables belong to a class and not to any individual instance. The concept of serialization is concerned with the object’s current state. Only data associated with a specific instance of a class is serialized, therefore static member fields are ignored during serialization.Halfbreed
B
73
  1. Instance Variables: These variables are serialized, so during deserialization we will get back the serialized state.

  2. Static Variables: These variables are not serialized, So during deserialization static variable value will loaded from the class.(Current value will be loaded.)

  3. transient Variables: transient variables are not serialized, so during deserialization those variables will be initialized with corresponding default values (ex: for objects null, int 0).

  4. Super class variables: If super class also implemented Serializable interface then those variables will be serialized, otherwise it won't serialize the super class variables. and while deserializing, JVM will run default constructor in super class and populates the default values. Same thing will happen for all superclasses.

Brazilin answered 10/5, 2013 at 7:43 Comment(2)
"So while deserialization static variable value will loaded from the class.(Current value will be loaded.)" What if Class is being de-serialized in a different JVM?Kamerman
@mdev: the correct statement would be that static variables are not touched at all. It makes no sense to say that the “static variable value will loaded from the class”—into itself.Pea
S
55

serialVersionUID is a special static variable used by the serialization and deserialization process, to verify that a local class is compatible with the class used to serialize an object. It's not just a static variable as others, which are definitely not serialized.

When an object of a class is first serialized, a class descriptor containing among other things the class name and serial version UID is written to the stream. When this is deserialized, the JVM checks if the serial version UID read from the stream is the same as the one of the local class. If they're not, it doesn't even try to deserialize the object, because it knows the classes are incompatible.

Stewart answered 12/6, 2012 at 16:45 Comment(5)
What does the term special static variable mean ?Mercie
It means that it's a static variable that's special. (Specifically, it's treated differently from other static variables in serialization.)Sol
It's special, because the serialization mechanism looks for this static variable to know what the serial version UID of the class is. All the other static variables are just ignored by the serialization mechanism.Stewart
Thanks for the precise answer, appreciate it.Mercie
Static variables belong to a class and not to any individual instance. The concept of serialization is concerned with the object’s current state. Only data associated with a specific instance of a class is serialized, therefore static member fields are ignored during serialization.Halfbreed
R
5

serialVersionUID is special and is not subject to these rules. There is code within the serialization machinery that specifically handles this field to perform the automatic version checks.

Rhaetian answered 12/6, 2012 at 16:44 Comment(0)
T
4

You can test this for yourself - here's some example code that should answer your question:

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;

class TestJava implements Serializable{
  public static int k = 10;
  public int j = 5;

  public static void main(String[] args) {

    TestJava tj1= new TestJava();
    TestJava tj2;

        try{ //serialization
            FileOutputStream fos = new FileOutputStream("myclass.ser");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(tj1);
            oos.close();
            fos.close();
            System.out.println("object serielized 1..."+tj1.j);
            System.out.println("object serielized 2..."+tj1.k);
            System.out.println("object serielized 3..."+k);
            k=++k; // 'k' value incrementd after serialization
          } catch(FileNotFoundException fnfe){
             fnfe.printStackTrace();
          } catch(IOException ioex){
             ioex.printStackTrace();
          }

          try{ //deserialization
              FileInputStream fis = new FileInputStream("myclass.ser");
              ObjectInputStream ois = new ObjectInputStream(fis);
              tj2 = (TestJava) ois.readObject();
              ois.close();
              fis.close();
              System.out.println("object DEEEEserielized 1..."+tj2.j);
              System.out.println("object DEEEEserielized 2..."+tj2.k); 
              System.out.println("object DEEEEserielized 3..."+k); 
            // in deserialization 'k' value is shown as incremented. 
            // That means Static varialbe 'K' is not serialized.
            // if 'K' value is serialized then, it has to show old value before incrementd the 'K' value.
            } catch(FileNotFoundException fnfe){
              fnfe.printStackTrace();
            } catch(IOException ioex){
              ioex.printStackTrace();
            } catch(ClassNotFoundException CNFE){
              CNFE.printStackTrace();                   
           }
      }
}

This will output the following:

object serielized 1...5
object serielized 2...10
object serielized 3...10
object DEEEEserielized 1...5
object DEEEEserielized 2...11
object DEEEEserielized 3...11

So we create an object of class TestJava with one static integer field and one non-static field. We serialize the object, then - after serialization - increment the static integer.

When we later deserialize the object, we see that it has the incremented value, implying that it was not serialized.

Thermoscope answered 1/2, 2015 at 17:15 Comment(1)
Thanks. static variables are not serialized, no matter where they're initialized.Asinine
F
2

The serialVersionUID is also serialized in this case.

Any static variable that is provided a value during class initialization is serialized.

However in normal cases, where you would provide the value to a static variable at the main class / run-time would not be serialized.

You can try to access the serialVersionUID by making it public and try to access it after deserialization.

You can refer "http://javabeginnerstutorial.com/core-java-tutorial/transient-vs-static-variable-java/" for more information.

Hope that helps. Cheers !!

Fleshly answered 26/2, 2017 at 12:55 Comment(1)
No static variable is serialized, whether or not it is provided with a value during class initialization. Your cited source and your answer are both incorrect, and your citation explicitly contradicts itself.Unlade
M
1

No, if a class have static variable then at the time of serialization that variable will be skipped . because static variable is unique for all object and serialization is used for only save the object properties ( state of object ). static variable is a property of class

Memoirs answered 7/11, 2017 at 11:47 Comment(0)
B
0

Below example explains about static ,instance,transient and super class varialbes serialization and their outputs.

Serializing class:

public class SerializeEx extends SuperSerializeEx implements Serializable {

    private static final long serialVersionUID = 1L;
    public static int staticNumber = 1234;
    public int instanceNumber = 1234;

    public SerializeEx() {
        staticNumber = 0;
        instanceNumber = 0;
        System.out.println("---sub class constructor---");
    }

    public SerializeEx(int staticNumber, int instanceNumber, int superNumber) {
        super(superNumber);
        this.staticNumber = staticNumber;
        this.instanceNumber = instanceNumber;
    }
}

Super Class:

public class SuperSerializeEx {

    public int superNumber;

    public SuperSerializeEx() {
        System.out.println("---super class constructor---");
        this.superNumber = 1000;
    }

    public SuperSerializeEx(int superNumber) {
        this.superNumber = superNumber;
    }
}

Serialization & Deserialization:

public class MainSerialization {

    public static void main(String[] args) {
        String fileName = "testing.txt";
        serialize(fileName);
        deSerialize(fileName);
    }

    public static void serialize(String fileName) {
        System.err.println("Serialize.....");
        SerializeEx serializeMe = new SerializeEx(10, 10, 10);
        FileOutputStream fos = null;
        ObjectOutputStream out = null;
        try {
            fos = new FileOutputStream(fileName);
            out = new ObjectOutputStream(fos);
            out.writeObject(serializeMe);
            out.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static void deSerialize(String fileName) {
        System.err.println("DeSerialize.....");
        SerializeEx time = null;
        FileInputStream fis = null;
        ObjectInputStream in = null;
        try {
            fis = new FileInputStream(fileName);
            in = new ObjectInputStream(fis);
            time = (SerializeEx) in.readObject();
            in.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        System.err.println("Instance Numer = " + time.instanceNumber + " \tStatic Number= " + time.staticNumber + " \t Super Number= " + time.superNumber);
        SerializeEx serializeMe = new SerializeEx(1001, 1001, 1001); //Modifying the static and instnce variables
        System.err.println("Instance Numer = " + time.instanceNumber + " \tStatic Number= " + time.staticNumber + " \t Super Number= " + time.superNumber);
    }
}

Output:

---super class constructor---
Serialize.....
DeSerialize.....
Instance Numer = 10     Static Number= 10      Super Number= 1000
Instance Numer = 10     Static Number= 1001    Super Number= 1000
Brazilin answered 10/5, 2013 at 7:54 Comment(1)
Examples explain nothing. They merely exhibit behaviour.Unlade
W
0

Yes, static variable will be serialized if it is initialized at the time of declaration.

For example,

case 1 : without initialization at the time of declaration

class Person implements Serializable{

  public String firstName;

  static  String lastName;  
}

public class Employee {

  public static void main(String[] args) {

      Person p = new Person();
      p.firstName="abc";
      p.lastName="xyz";
      //to do serialization

  }

}

output :

//after deserialization

 firstName= abc

 lastName= null

case 2 : with initialization at the time of declaration

class Person implements Serializable{

  public String firstName=="abc";

  static  String lastName="pqr";  
}

public class Employee {

  public static void main(String[] args) {

      Person p = new Person();
      p.firstName="abc";
      p.lastName="xyz";
      //to do serialization

  }

 }

output :

//after deserialization

firstName= abc

lastName= pqr
Windowshop answered 11/7, 2018 at 12:34 Comment(0)
D
0

Any static variable which has been initialised at the time of declaration will be serialized.

Digitoxin answered 23/6, 2019 at 17:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.