[java] What is object serialization?

What is meant by "object serialization"? Can you please explain it with some examples?

This question is related to java serialization object-serialization

The answer is


Serialization is the conversion of an object to a series of bytes, so that the object can be easily saved to persistent storage or streamed across a communication link. The byte stream can then be deserialized - converted into a replica of the original object.


|*| Serializing a class : Converting an object to bytes and bytes back to object (Deserialization).

class NamCls implements Serializable
{
    int NumVar;
    String NamVar;
}

|=> Object-Serialization is process of converting the state of an object into steam of bytes.

  • |-> Implement when you want the object to exist beyond the lifetime of the JVM.
  • |-> Serialized Object can be stored in Database.
  • |-> Serializable-objects cannot be read and understood by humans so we can acheive security.

|=> Object-Deserialization is the process of getting the state of an object and store it into an object(java.lang.Object).

  • |-> Before storing its state it checks whether serialVersionUID form input-file/network and .class file serialVersionUID are same.
    &nbsp&nbspIf not throw java.io.InvalidClassException.

|=> A Java object is only serializable, if its class or any of its superclasses

  • implements either the java.io.Serializable interface or
  • its subinterface, java.io.Externalizable.

|=> Static fields in a class cannot be serialized.

class NamCls implements Serializable
{
    int NumVar;
    static String NamVar = "I won't be serializable";;
}

|=> If you do not want to serialise a variable of a class use transient keyword

class NamCls implements Serializable
{
    int NumVar;
    transient String NamVar;
}

|=> If a class implements serializable then all its sub classes will also be serializable.

|=> If a class has a reference of another class, all the references must be Serializable otherwise serialization process will not be performed. In such case,
NotSerializableException is thrown at runtime.


Serialization is the process of turning a Java object into byte array and then back into object again with its preserved state. Useful for various things like sending objects over network or caching things to disk.

Read more from this short article which explains programming part of the process quite well and then move over to to Serializable javadoc. You may also be interested in reading this related question.


Serialization is the process of converting an object's state to bits so that it can be stored on a hard drive. When you deserialize the same object, it will retain its state later. It lets you recreate objects without having to save the objects' properties by hand.

http://en.wikipedia.org/wiki/Serialization


Return the file as an Object : http://www.tutorialspoint.com/java/java_serialization.htm

        import java.io.*;

        public class SerializeDemo
        {
           public static void main(String [] args)
           {
              Employee e = new Employee();
              e.name = "Reyan Ali";
              e.address = "Phokka Kuan, Ambehta Peer";
              e.SSN = 11122333;
              e.number = 101;

              try
              {
                 FileOutputStream fileOut =
                 new FileOutputStream("/tmp/employee.ser");
                 ObjectOutputStream out = new ObjectOutputStream(fileOut);
                 out.writeObject(e);
                 out.close();
                 fileOut.close();
                 System.out.printf("Serialized data is saved in /tmp/employee.ser");
              }catch(IOException i)
              {
                  i.printStackTrace();
              }
           }
        }

    import java.io.*;
    public class DeserializeDemo
    {
       public static void main(String [] args)
       {
          Employee e = null;
          try
          {
             FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn);
             e = (Employee) in.readObject();
             in.close();
             fileIn.close();
          }catch(IOException i)
          {
             i.printStackTrace();
             return;
          }catch(ClassNotFoundException c)
          {
             System.out.println("Employee class not found");
             c.printStackTrace();
             return;
          }
          System.out.println("Deserialized Employee...");
          System.out.println("Name: " + e.name);
          System.out.println("Address: " + e.address);
          System.out.println("SSN: " + e.SSN);
          System.out.println("Number: " + e.number);
        }
    }

Serialization is taking a "live" object in memory and converting it to a format that can be stored somewhere (eg. in memory, on disk) and later "deserialized" back into a live object.


Java Object Serialization

enter image description here

Serialization is a mechanism to transform a graph of Java objects into an array of bytes for storage(to disk file) or transmission(across a network), then by using deserialization we can restore the graph of objects. Graphs of objects are restored correctly using a reference sharing mechanism. But before storing, check whether serialVersionUID from input-file/network and .class file serialVersionUID are the same. If not, throw a java.io.InvalidClassException.

Each versioned class must identify the original class version for which it is capable of writing streams and from which it can read. For example, a versioned class must declare:

serialVersionUID Syntax

// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L;
private static final long serialVersionUID = 3487495895819393L;

serialVersionUID is essential to the serialization process. But it is optional for the developer to add it into the java source file. If a serialVersionUID is not included, the serialization runtime will generate a serialVersionUID and associate it with the class. The serialized object will contain this serialVersionUID along with other data.

Note - It is strongly recommended that all serializable classes explicitly declare a serialVersionUID, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected serialVersionUID conflicts during deserialization, causing deserialization to fail.

Inspecting Serializable Classes

enter image description here


A Java object is only serializable. if a class or any of its superclasses implements either the java.io.Serializable interface or its subinterface, java.io.Externalizable.

  • A class must implement java.io.Serializable interface in order to serialize its object successfully. Serializable is a marker interface and used to inform the compiler that the class implementing it has to be added serializable behavior. Here Java Virtual Machine (JVM) is responsible for its automatic serialization.

    transient Keyword: java.io.Serializable interface

    While serializing an object, if we don't want certain data members of the object to be serialized we can use the transient modifier. The transient keyword will prevent that data member from being serialized.

    • Fields declared as transient or static are ignored by the serialization process.

    TRANSIENT & VOLATILE

    +--------------+--------+-------------------------------------+
    |  Flag Name   |  Value | Interpretation                      |
    +--------------+--------+-------------------------------------+
    | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.|
    +--------------+--------+-------------------------------------+
    |ACC_TRANSIENT | 0x0080 | Declared transient; not written or  |
    |              |        | read by a persistent object manager.|
    +--------------+--------+-------------------------------------+
    
    class Employee implements Serializable {
        private static final long serialVersionUID = 2L;
        static int id;
    
        int eno; 
        String name;
        transient String password; // Using transient keyword means its not going to be Serialized.
    }
    
  • Implementing the Externalizable interface allows the object to assume complete control over the contents and format of the object's serialized form. The methods of the Externalizable interface, writeExternal and readExternal, are called to save and restore the objects state. When implemented by a class they can write and read their own state using all of the methods of ObjectOutput and ObjectInput. It is the responsibility of the objects to handle any versioning that occurs.

    class Emp implements Externalizable {
        int eno; 
        String name;
        transient String password; // No use of transient, we need to take care of write and read.
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(eno);
            out.writeUTF(name);
            //out.writeUTF(password);
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.eno = in.readInt();
            this.name = in.readUTF();
            //this.password = in.readUTF(); // java.io.EOFException
        }
    }
    
  • Only objects that support the java.io.Serializable or java.io.Externalizable interface can be written to/read from streams. The class of each serializable object is encoded including the class name and signature of the class, the values of the object's fields and arrays, and the closure of any other objects referenced from the initial objects.

Serializable Example For Files

public class SerializationDemo {
    static String fileName = "D:/serializable_file.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        Employee emp = new Employee( );
        Employee.id = 1; // Can not Serialize Class data.
        emp.eno = 77;
        emp.name = "Yash";
        emp.password = "confidential";
        objects_WriteRead(emp, fileName);

        Emp e = new Emp( );
        e.eno = 77;
        e.name = "Yash";
        e.password = "confidential";
        objects_WriteRead_External(e, fileName);

        /*String stubHost = "127.0.0.1";
        Integer anyFreePort = 7777;
        socketRead(anyFreePort); //Thread1
        socketWrite(emp, stubHost, anyFreePort); //Thread2*/

    }
    public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
        FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );
        objectOut.writeObject( obj );
        objectOut.close();
        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            FileInputStream fis = new FileInputStream( new File( serFilename ) );
            ObjectInputStream ois = new ObjectInputStream( fis );
            Object readObject;
            readObject = ois.readObject();
            String calssName = readObject.getClass().getName();
            System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException

            Employee emp = (Employee) readObject;
            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
        FileOutputStream fos = new FileOutputStream(new File( serFilename ));
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        obj.writeExternal( objectOut );
        objectOut.flush();

        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            // create a new instance and read the assign the contents from stream.
            Emp emp = new Emp();

            FileInputStream fis = new FileInputStream(new File( serFilename ));
            ObjectInputStream ois = new ObjectInputStream( fis );

            emp.readExternal(ois);

            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Serializable Example Over Network

Distributing object's state across different address spaces, either in different processes on the same computer, or even in multiple computers connected via a network, but which work together by sharing data and invoking methods.

/**
 * Creates a stream socket and connects it to the specified port number on the named host. 
 */
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
    try { // CLIENT - Stub[marshalling]
        Socket client = new Socket(stubHost, anyFreePort);
        ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
        out.writeObject(objectToSend);
        out.flush();
        client.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// Creates a server socket, bound to the specified port. 
public static void socketRead(  Integer anyFreePort ) {
    try { // SERVER - Stub[unmarshalling ]
        ServerSocket serverSocket = new ServerSocket( anyFreePort );
        System.out.println("Server serves on port and waiting for a client to communicate");
            /*System.in.read();
            System.in.read();*/

        Socket socket = serverSocket.accept();
        System.out.println("Client request to communicate on port server accepts it.");

        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Employee objectReceived = (Employee) in.readObject();
        System.out.println("Server Obj : "+ objectReceived.name );

        socket.close();
        serverSocket.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

@see


Serialization is taking a "live" object in memory and converting it to a format that can be stored somewhere (eg. in memory, on disk) and later "deserialized" back into a live object.


My Two cents from my own blog:

Here is a detailed explanation of the Serialization: (my own blog)

Serialization:

Serialization is the process of persisting the state of an object. It is represented and stored in the form of a sequence of bytes. This can be stored in a file. The process to read the state of the object from the file and restoring it is called deserialization.

What is the need of Serialization?

In modern day architecture, there is always a need to store object state and then retrieve it. For example in Hibernate, to store a object we should make the class Serializable. What it does, is that once the object state is saved in the form of bytes it can be transferred to another system which can then read from the state and retrieve the class. The object state can come from a database or a different jvm or from a separate component. With the help of Serialization we can retrieve the Object state.

Code Example and explanation:

First let's have a look at the Item Class:

public class Item implements Serializable{

    /**
    *  This is the Serializable class
    */
    private static final long serialVersionUID = 475918891428093041L;
    private Long itemId;
    private String itemName;
    private transient Double itemCostPrice;
    public Item(Long itemId, String itemName, Double itemCostPrice) {
        super();
        this.itemId = itemId;
        this.itemName = itemName;
        this.itemCostPrice = itemCostPrice;
      }

      public Long getItemId() {
          return itemId;
      }

     @Override
      public String toString() {
          return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
       }


       public void setItemId(Long itemId) {
           this.itemId = itemId;
       }

       public String getItemName() {
           return itemName;
       }
       public void setItemName(String itemName) {
            this.itemName = itemName;
        }

       public Double getItemCostPrice() {
            return itemCostPrice;
        }

        public void setItemCostPrice(Double itemCostPrice) {
             this.itemCostPrice = itemCostPrice;
        }
}

In the above code it can be seen that Item class implements Serializable.

This is the interface that enables a class to be serializable.

Now we can see a variable called serialVersionUID is initialized to Long variable. This number is calculated by the compiler based on the state of the class and the class attributes. This is the number that will help the jvm identify the state of an object when it reads the state of the object from file.

For that we can have a look at the official Oracle Documentation:

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long: ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members.

If you have noticed there is another keyword we have used which is transient.

If a field is not serializable, it must be marked transient. Here we marked the itemCostPrice as transient and don't want it to be written in a file

Now let's have a look on how to write the state of an object in the file and then read it from there.

public class SerializationExample {

    public static void main(String[] args){
        serialize();
       deserialize();
    } 

    public static void serialize(){

         Item item = new Item(1L,"Pen", 12.55);
         System.out.println("Before Serialization" + item);

         FileOutputStream fileOut;
         try {
             fileOut = new FileOutputStream("/tmp/item.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut);
             out.writeObject(item);
             out.close();
             fileOut.close();
             System.out.println("Serialized data is saved in /tmp/item.ser");
           } catch (FileNotFoundException e) {

                  e.printStackTrace();
           } catch (IOException e) {

                  e.printStackTrace();
           }
      }

    public static void deserialize(){
        Item item;

        try {
                FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
                ObjectInputStream in = new ObjectInputStream(fileIn);
                item = (Item) in.readObject();
                System.out.println("Serialized data is read from /tmp/item.ser");
                System.out.println("After Deserialization" + item);
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        } catch (IOException e) {
               e.printStackTrace();
        } catch (ClassNotFoundException e) {
               e.printStackTrace();
        }
     }
}

In the above we can see an example of serialization and deserialization of an object.

For that we used two classes. For serializing the object we have used ObjectOutputStream. We have used the method writeObject to write the object in the file.

For Deserializing we have used ObjectInputStream which reads from the object from the file. It uses readObject to read the object data from the file.

The output of the above code would be like:

Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]

Notice that itemCostPrice from deserialized object is null as it was not written.

We have already discussed the basics of Java Serialization in part I of this article.

Now let's discuss it deeply and how it works.

First let's start with the serialversionuid.

The serialVersionUID is used as a version control in a Serializable class.

If you do not explicitly declare a serialVersionUID, JVM will do it for you automatically, based on various properties of the Serializable class.

Java's Algorithm of Calculating serialversionuid (Read more details here)

  1. The class name.
    1. The class modifiers written as a 32-bit integer.
    2. The name of each interface sorted by name.
    3. For each field of the class sorted by field name (except private static and private transient fields: The name of the field. The modifiers of the field written as a 32-bit integer. The descriptor of the field.
    4. If a class initializer exists, write out the following: The name of the method, .
    5. The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
    6. The descriptor of the method, ()V.
    7. For each non-private constructor sorted by method name and signature: The name of the method, . The modifiers of the method written as a 32-bit integer. The descriptor of the method.
    8. For each non-private method sorted by method name and signature: The name of the method. The modifiers of the method written as a 32-bit integer. The descriptor of the method.
    9. The SHA-1 algorithm is executed on the stream of bytes produced by DataOutputStream and produces five 32-bit values sha[0..4]. The hash value is assembled from the first and second 32-bit values of the SHA-1 message digest. If the result of the message digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named sha, the hash value would be computed as follows:
    long hash = ((sha[0] >>> 24) & 0xFF) |
>            ((sha[0] >>> 16) & 0xFF) << 8 |
>            ((sha[0] >>> 8) & 0xFF) << 16 |
>            ((sha[0] >>> 0) & 0xFF) << 24 |
>            ((sha[1] >>> 24) & 0xFF) << 32 |
>            ((sha[1] >>> 16) & 0xFF) << 40 |
>            ((sha[1] >>> 8) & 0xFF) << 48 |
>        ((sha[1] >>> 0) & 0xFF) << 56;

Java's serialization algorithm

The algorithm to serialize an object is described as below:
1. It writes out the metadata of the class associated with an instance.
2. It recursively writes out the description of the superclass until it finds java.lang.object.
3. Once it finishes writing the metadata information, it then starts with the actual data associated with the instance. But this time, it starts from the topmost superclass.
4. It recursively writes the data associated with the instance, starting from the least superclass to the most-derived class.

Things To Keep In Mind:

  1. Static fields in a class cannot be serialized.

    public class A implements Serializable{
         String s;
         static String staticString = "I won't be serializable";
    }
    
  2. If the serialversionuid is different in the read class it will throw a InvalidClassException exception.

  3. If a class implements serializable then all its sub classes will also be serializable.

    public class A implements Serializable {....};
    
    public class B extends A{...} //also Serializable
    
  4. If a class has a reference of another class, all the references must be Serializable otherwise serialization process will not be performed. In such case, NotSerializableException is thrown at runtime.

Eg:

public class B{
     String s,
     A a; // class A needs to be serializable i.e. it must implement Serializable
}

Serialization is taking a "live" object in memory and converting it to a format that can be stored somewhere (eg. in memory, on disk) and later "deserialized" back into a live object.


Serialization is taking a "live" object in memory and converting it to a format that can be stored somewhere (eg. in memory, on disk) and later "deserialized" back into a live object.


Serialization is the process of turning a Java object into byte array and then back into object again with its preserved state. Useful for various things like sending objects over network or caching things to disk.

Read more from this short article which explains programming part of the process quite well and then move over to to Serializable javadoc. You may also be interested in reading this related question.


I liked the way @OscarRyz presents. Although here i am continuing the story of serialization which was originally written by @amitgupta.

Even though knowing about the robot class structure and having serialized data Earth's scientist were not able to deserialize the data which can make robots working.

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

Mars's scientists were waiting for the complete payment. Once the payment was done Mars's scientists shared the serialversionUID with Earth's scientists. Earth's scientist set it to robot class and everything became fine.


Serialization is the process of converting an object's state to bits so that it can be stored on a hard drive. When you deserialize the same object, it will retain its state later. It lets you recreate objects without having to save the objects' properties by hand.

http://en.wikipedia.org/wiki/Serialization


You can think of serialization as the process of converting an object instance into a sequence of bytes (which may be binary or not depending on the implementation).

It is very useful when you want to transmit one object data across the network, for instance from one JVM to another.

In Java, the serialization mechanism is built into the platform, but you need to implement the Serializable interface to make an object serializable.

You can also prevent some data in your object from being serialized by marking the attribute as transient.

Finally you can override the default mechanism, and provide your own; this may be suitable in some special cases. To do this, you use one of the hidden features in java.

It is important to notice that what gets serialized is the "value" of the object, or the contents, and not the class definition. Thus methods are not serialized.

Here is a very basic sample with comments to facilitate its reading:

import java.io.*;
import java.util.*;

// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  { 

        // Create a sample object, that contains the default values.
        SerializationSample instance = new SerializationSample();

        // The "ObjectOutputStream" class has the default 
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream( 
                               // By using "FileOutputStream" we will 
                               // Write it to a File in the file system
                               // It could have been a Socket to another 
                               // machine, a database, an in memory array, etc.
                               new FileOutputStream(new File("o.ser")));

        // do the magic  
        oos.writeObject( instance );
        // close the writing.
        oos.close();
    }
}

When we run this program, the file "o.ser" is created and we can see what happened behind.

If we change the value of: someInteger to, for example Integer.MAX_VALUE, we may compare the output to see what the difference is.

Here's a screenshot showing precisely that difference:

alt text

Can you spot the differences? ;)

There is an additional relevant field in Java serialization: The serialversionUID but I guess this is already too long to cover it.


My Two cents from my own blog:

Here is a detailed explanation of the Serialization: (my own blog)

Serialization:

Serialization is the process of persisting the state of an object. It is represented and stored in the form of a sequence of bytes. This can be stored in a file. The process to read the state of the object from the file and restoring it is called deserialization.

What is the need of Serialization?

In modern day architecture, there is always a need to store object state and then retrieve it. For example in Hibernate, to store a object we should make the class Serializable. What it does, is that once the object state is saved in the form of bytes it can be transferred to another system which can then read from the state and retrieve the class. The object state can come from a database or a different jvm or from a separate component. With the help of Serialization we can retrieve the Object state.

Code Example and explanation:

First let's have a look at the Item Class:

public class Item implements Serializable{

    /**
    *  This is the Serializable class
    */
    private static final long serialVersionUID = 475918891428093041L;
    private Long itemId;
    private String itemName;
    private transient Double itemCostPrice;
    public Item(Long itemId, String itemName, Double itemCostPrice) {
        super();
        this.itemId = itemId;
        this.itemName = itemName;
        this.itemCostPrice = itemCostPrice;
      }

      public Long getItemId() {
          return itemId;
      }

     @Override
      public String toString() {
          return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
       }


       public void setItemId(Long itemId) {
           this.itemId = itemId;
       }

       public String getItemName() {
           return itemName;
       }
       public void setItemName(String itemName) {
            this.itemName = itemName;
        }

       public Double getItemCostPrice() {
            return itemCostPrice;
        }

        public void setItemCostPrice(Double itemCostPrice) {
             this.itemCostPrice = itemCostPrice;
        }
}

In the above code it can be seen that Item class implements Serializable.

This is the interface that enables a class to be serializable.

Now we can see a variable called serialVersionUID is initialized to Long variable. This number is calculated by the compiler based on the state of the class and the class attributes. This is the number that will help the jvm identify the state of an object when it reads the state of the object from file.

For that we can have a look at the official Oracle Documentation:

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long: ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members.

If you have noticed there is another keyword we have used which is transient.

If a field is not serializable, it must be marked transient. Here we marked the itemCostPrice as transient and don't want it to be written in a file

Now let's have a look on how to write the state of an object in the file and then read it from there.

public class SerializationExample {

    public static void main(String[] args){
        serialize();
       deserialize();
    } 

    public static void serialize(){

         Item item = new Item(1L,"Pen", 12.55);
         System.out.println("Before Serialization" + item);

         FileOutputStream fileOut;
         try {
             fileOut = new FileOutputStream("/tmp/item.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut);
             out.writeObject(item);
             out.close();
             fileOut.close();
             System.out.println("Serialized data is saved in /tmp/item.ser");
           } catch (FileNotFoundException e) {

                  e.printStackTrace();
           } catch (IOException e) {

                  e.printStackTrace();
           }
      }

    public static void deserialize(){
        Item item;

        try {
                FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
                ObjectInputStream in = new ObjectInputStream(fileIn);
                item = (Item) in.readObject();
                System.out.println("Serialized data is read from /tmp/item.ser");
                System.out.println("After Deserialization" + item);
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        } catch (IOException e) {
               e.printStackTrace();
        } catch (ClassNotFoundException e) {
               e.printStackTrace();
        }
     }
}

In the above we can see an example of serialization and deserialization of an object.

For that we used two classes. For serializing the object we have used ObjectOutputStream. We have used the method writeObject to write the object in the file.

For Deserializing we have used ObjectInputStream which reads from the object from the file. It uses readObject to read the object data from the file.

The output of the above code would be like:

Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]

Notice that itemCostPrice from deserialized object is null as it was not written.

We have already discussed the basics of Java Serialization in part I of this article.

Now let's discuss it deeply and how it works.

First let's start with the serialversionuid.

The serialVersionUID is used as a version control in a Serializable class.

If you do not explicitly declare a serialVersionUID, JVM will do it for you automatically, based on various properties of the Serializable class.

Java's Algorithm of Calculating serialversionuid (Read more details here)

  1. The class name.
    1. The class modifiers written as a 32-bit integer.
    2. The name of each interface sorted by name.
    3. For each field of the class sorted by field name (except private static and private transient fields: The name of the field. The modifiers of the field written as a 32-bit integer. The descriptor of the field.
    4. If a class initializer exists, write out the following: The name of the method, .
    5. The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
    6. The descriptor of the method, ()V.
    7. For each non-private constructor sorted by method name and signature: The name of the method, . The modifiers of the method written as a 32-bit integer. The descriptor of the method.
    8. For each non-private method sorted by method name and signature: The name of the method. The modifiers of the method written as a 32-bit integer. The descriptor of the method.
    9. The SHA-1 algorithm is executed on the stream of bytes produced by DataOutputStream and produces five 32-bit values sha[0..4]. The hash value is assembled from the first and second 32-bit values of the SHA-1 message digest. If the result of the message digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named sha, the hash value would be computed as follows:
    long hash = ((sha[0] >>> 24) & 0xFF) |
>            ((sha[0] >>> 16) & 0xFF) << 8 |
>            ((sha[0] >>> 8) & 0xFF) << 16 |
>            ((sha[0] >>> 0) & 0xFF) << 24 |
>            ((sha[1] >>> 24) & 0xFF) << 32 |
>            ((sha[1] >>> 16) & 0xFF) << 40 |
>            ((sha[1] >>> 8) & 0xFF) << 48 |
>        ((sha[1] >>> 0) & 0xFF) << 56;

Java's serialization algorithm

The algorithm to serialize an object is described as below:
1. It writes out the metadata of the class associated with an instance.
2. It recursively writes out the description of the superclass until it finds java.lang.object.
3. Once it finishes writing the metadata information, it then starts with the actual data associated with the instance. But this time, it starts from the topmost superclass.
4. It recursively writes the data associated with the instance, starting from the least superclass to the most-derived class.

Things To Keep In Mind:

  1. Static fields in a class cannot be serialized.

    public class A implements Serializable{
         String s;
         static String staticString = "I won't be serializable";
    }
    
  2. If the serialversionuid is different in the read class it will throw a InvalidClassException exception.

  3. If a class implements serializable then all its sub classes will also be serializable.

    public class A implements Serializable {....};
    
    public class B extends A{...} //also Serializable
    
  4. If a class has a reference of another class, all the references must be Serializable otherwise serialization process will not be performed. In such case, NotSerializableException is thrown at runtime.

Eg:

public class B{
     String s,
     A a; // class A needs to be serializable i.e. it must implement Serializable
}

|*| Serializing a class : Converting an object to bytes and bytes back to object (Deserialization).

class NamCls implements Serializable
{
    int NumVar;
    String NamVar;
}

|=> Object-Serialization is process of converting the state of an object into steam of bytes.

  • |-> Implement when you want the object to exist beyond the lifetime of the JVM.
  • |-> Serialized Object can be stored in Database.
  • |-> Serializable-objects cannot be read and understood by humans so we can acheive security.

|=> Object-Deserialization is the process of getting the state of an object and store it into an object(java.lang.Object).

  • |-> Before storing its state it checks whether serialVersionUID form input-file/network and .class file serialVersionUID are same.
    &nbsp&nbspIf not throw java.io.InvalidClassException.

|=> A Java object is only serializable, if its class or any of its superclasses

  • implements either the java.io.Serializable interface or
  • its subinterface, java.io.Externalizable.

|=> Static fields in a class cannot be serialized.

class NamCls implements Serializable
{
    int NumVar;
    static String NamVar = "I won't be serializable";;
}

|=> If you do not want to serialise a variable of a class use transient keyword

class NamCls implements Serializable
{
    int NumVar;
    transient String NamVar;
}

|=> If a class implements serializable then all its sub classes will also be serializable.

|=> If a class has a reference of another class, all the references must be Serializable otherwise serialization process will not be performed. In such case,
NotSerializableException is thrown at runtime.


You can think of serialization as the process of converting an object instance into a sequence of bytes (which may be binary or not depending on the implementation).

It is very useful when you want to transmit one object data across the network, for instance from one JVM to another.

In Java, the serialization mechanism is built into the platform, but you need to implement the Serializable interface to make an object serializable.

You can also prevent some data in your object from being serialized by marking the attribute as transient.

Finally you can override the default mechanism, and provide your own; this may be suitable in some special cases. To do this, you use one of the hidden features in java.

It is important to notice that what gets serialized is the "value" of the object, or the contents, and not the class definition. Thus methods are not serialized.

Here is a very basic sample with comments to facilitate its reading:

import java.io.*;
import java.util.*;

// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  { 

        // Create a sample object, that contains the default values.
        SerializationSample instance = new SerializationSample();

        // The "ObjectOutputStream" class has the default 
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream( 
                               // By using "FileOutputStream" we will 
                               // Write it to a File in the file system
                               // It could have been a Socket to another 
                               // machine, a database, an in memory array, etc.
                               new FileOutputStream(new File("o.ser")));

        // do the magic  
        oos.writeObject( instance );
        // close the writing.
        oos.close();
    }
}

When we run this program, the file "o.ser" is created and we can see what happened behind.

If we change the value of: someInteger to, for example Integer.MAX_VALUE, we may compare the output to see what the difference is.

Here's a screenshot showing precisely that difference:

alt text

Can you spot the differences? ;)

There is an additional relevant field in Java serialization: The serialversionUID but I guess this is already too long to cover it.


Serialization is the process of converting an object's state to bits so that it can be stored on a hard drive. When you deserialize the same object, it will retain its state later. It lets you recreate objects without having to save the objects' properties by hand.

http://en.wikipedia.org/wiki/Serialization


Daring to answer the 6-year-old question, adding just a very high-level understanding for people new to Java

What is Serialization?

Converting an object to bytes

What is Deserialization?

Converting bytes back to an object (Deserialization).

When is serialization used?

When we want to Persist the Object. When we want the object to exist beyond the lifetime of the JVM.

Real World Example:

ATM: When the account holder tries to withdraw money from the server through ATM, the account holder information like withdrawal details will be serialized and sent to the server where the details are deserialized and used to perform operations.

How serialization is performed in java.

  1. Implement java.io.Serializable interface (marker interface so no method to implement).

  2. Persist the object: Use java.io.ObjectOutputStream class, a filter stream which is a wrapper around a lower-level byte stream (to write Object to file systems or transfer a flattened object across a network wire and rebuilt on the other side).

    • writeObject(<<instance>>) - to write an object
    • readObject() - to read an serialized Object

Remember:

When you serialize an object, only the object's state will be saved, not the object's class file or methods.

When you serialized a 2-byte object, you see 51 bytes serialized file.

Steps how the object is serialized and de-serialized.

Answer for: How did it convert to 51 bytes file?

  • First writes the serialization stream magic data (STREAM_MAGIC= "AC ED" and STREAM_VERSION=version of the JVM).
  • Then it writes out the metadata of the class associated with an instance (length of the class, the name of the class, serialVersionUID).
  • Then it recursively writes out the metadata of the superclass until it finds java.lang.Object.
  • Then starts with the actual data associated with the instance.
  • Finally writes the data of objects associated with the instance starting from metadata to the actual content.

If you are interested in more in-depth information about Java Serialization please check this link.

Edit : One more good link to read.

This will answer a few frequent questions:

  1. How not to serialize any field in class.
    Ans: use transient keyword

  2. When child class is serialized does parent class get serialized?
    Ans: No, If a parent is not extending the Serializable interface parents field don't get serialized.

  3. When a parent is serialized does child class get serialized?
    Ans: Yes, by default child class also gets serialized.

  4. How to avoid child class from getting serialized?
    Ans: a. Override writeObject and readObject method and throw NotSerializableException.

    b. also you can mark all fields transient in child class.

  5. Some system-level classes such as Thread, OutputStream, and its subclasses, and Socket are not serializable.

You can think of serialization as the process of converting an object instance into a sequence of bytes (which may be binary or not depending on the implementation).

It is very useful when you want to transmit one object data across the network, for instance from one JVM to another.

In Java, the serialization mechanism is built into the platform, but you need to implement the Serializable interface to make an object serializable.

You can also prevent some data in your object from being serialized by marking the attribute as transient.

Finally you can override the default mechanism, and provide your own; this may be suitable in some special cases. To do this, you use one of the hidden features in java.

It is important to notice that what gets serialized is the "value" of the object, or the contents, and not the class definition. Thus methods are not serialized.

Here is a very basic sample with comments to facilitate its reading:

import java.io.*;
import java.util.*;

// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  { 

        // Create a sample object, that contains the default values.
        SerializationSample instance = new SerializationSample();

        // The "ObjectOutputStream" class has the default 
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream( 
                               // By using "FileOutputStream" we will 
                               // Write it to a File in the file system
                               // It could have been a Socket to another 
                               // machine, a database, an in memory array, etc.
                               new FileOutputStream(new File("o.ser")));

        // do the magic  
        oos.writeObject( instance );
        // close the writing.
        oos.close();
    }
}

When we run this program, the file "o.ser" is created and we can see what happened behind.

If we change the value of: someInteger to, for example Integer.MAX_VALUE, we may compare the output to see what the difference is.

Here's a screenshot showing precisely that difference:

alt text

Can you spot the differences? ;)

There is an additional relevant field in Java serialization: The serialversionUID but I guess this is already too long to cover it.


Serialization means persisting objects in java. If you want to save the state of the object and want to rebuild the state later (may be in another JVM) serialization can be used.

Note that the properties of an object is only going to be saved. If you want to resurrect the object again you should have the class file, because the member variables only will be stored and not the member functions.

eg:

ObjectInputStream oos = new ObjectInputStream(                                 
                                 new FileInputStream(  new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();

The Searializable is a marker interface which marks that your class is serializable. Marker interface means that it is just an empty interface and using that interface will notify the JVM that this class can be made serializable.


Serialization is the process of saving an object in a storage medium (such as a file, or a memory buffer) or to transmit it over a network connection in binary form. The serialized objects are JVM independent and can be re-serialized by any JVM. In this case the "in memory" java objects state are converted into a byte stream. This type of the file can not be understood by the user. It is a special types of object i.e. reused by the JVM (Java Virtual Machine). This process of serializing an object is also called deflating or marshalling an object.

The object to be serialized must implement java.io.Serializable Interface. Default serialization mechanism for an object writes the class of the object, the class signature, and the values of all non-transient and non-static fields.

class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,

ObjectOutput interface extends the DataOutput interface and adds methods for serializing objects and writing bytes to the file. The ObjectOutputStream extends java.io.OutputStream and implements ObjectOutput interface. It serializes objects, arrays, and other values to a stream. Thus the constructor of ObjectOutputStream is written as:

ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));

Above code has been used to create the instance of the ObjectOutput class with the ObjectOutputStream( ) constructor which takes the instance of the FileOuputStream as a parameter.

The ObjectOutput interface is used by implementing the ObjectOutputStream class. The ObjectOutputStream is constructed to serialize the object.

Deserializing an Object in java

The opposite operation of the serialization is called deserialization i.e. to extract the data from a series of bytes is s known as deserialization which is also called inflating or unmarshalling.

ObjectInputStream extends java.io.InputStream and implements ObjectInput interface. It deserializes objects, arrays, and other values from an input stream. Thus the constructor of ObjectInputStream is written as:

ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));

Above code of the program creates the instance of the ObjectInputStream class to deserialize that file which had been serialized by the ObjectInputStream class. The above code creates the instance using the instance of the FileInputStream class which holds the specified file object which has to be deserialized because the ObjectInputStream() constructor needs the input stream.


Java Object Serialization

enter image description here

Serialization is a mechanism to transform a graph of Java objects into an array of bytes for storage(to disk file) or transmission(across a network), then by using deserialization we can restore the graph of objects. Graphs of objects are restored correctly using a reference sharing mechanism. But before storing, check whether serialVersionUID from input-file/network and .class file serialVersionUID are the same. If not, throw a java.io.InvalidClassException.

Each versioned class must identify the original class version for which it is capable of writing streams and from which it can read. For example, a versioned class must declare:

serialVersionUID Syntax

// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L;
private static final long serialVersionUID = 3487495895819393L;

serialVersionUID is essential to the serialization process. But it is optional for the developer to add it into the java source file. If a serialVersionUID is not included, the serialization runtime will generate a serialVersionUID and associate it with the class. The serialized object will contain this serialVersionUID along with other data.

Note - It is strongly recommended that all serializable classes explicitly declare a serialVersionUID, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected serialVersionUID conflicts during deserialization, causing deserialization to fail.

Inspecting Serializable Classes

enter image description here


A Java object is only serializable. if a class or any of its superclasses implements either the java.io.Serializable interface or its subinterface, java.io.Externalizable.

  • A class must implement java.io.Serializable interface in order to serialize its object successfully. Serializable is a marker interface and used to inform the compiler that the class implementing it has to be added serializable behavior. Here Java Virtual Machine (JVM) is responsible for its automatic serialization.

    transient Keyword: java.io.Serializable interface

    While serializing an object, if we don't want certain data members of the object to be serialized we can use the transient modifier. The transient keyword will prevent that data member from being serialized.

    • Fields declared as transient or static are ignored by the serialization process.

    TRANSIENT & VOLATILE

    +--------------+--------+-------------------------------------+
    |  Flag Name   |  Value | Interpretation                      |
    +--------------+--------+-------------------------------------+
    | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.|
    +--------------+--------+-------------------------------------+
    |ACC_TRANSIENT | 0x0080 | Declared transient; not written or  |
    |              |        | read by a persistent object manager.|
    +--------------+--------+-------------------------------------+
    
    class Employee implements Serializable {
        private static final long serialVersionUID = 2L;
        static int id;
    
        int eno; 
        String name;
        transient String password; // Using transient keyword means its not going to be Serialized.
    }
    
  • Implementing the Externalizable interface allows the object to assume complete control over the contents and format of the object's serialized form. The methods of the Externalizable interface, writeExternal and readExternal, are called to save and restore the objects state. When implemented by a class they can write and read their own state using all of the methods of ObjectOutput and ObjectInput. It is the responsibility of the objects to handle any versioning that occurs.

    class Emp implements Externalizable {
        int eno; 
        String name;
        transient String password; // No use of transient, we need to take care of write and read.
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(eno);
            out.writeUTF(name);
            //out.writeUTF(password);
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.eno = in.readInt();
            this.name = in.readUTF();
            //this.password = in.readUTF(); // java.io.EOFException
        }
    }
    
  • Only objects that support the java.io.Serializable or java.io.Externalizable interface can be written to/read from streams. The class of each serializable object is encoded including the class name and signature of the class, the values of the object's fields and arrays, and the closure of any other objects referenced from the initial objects.

Serializable Example For Files

public class SerializationDemo {
    static String fileName = "D:/serializable_file.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        Employee emp = new Employee( );
        Employee.id = 1; // Can not Serialize Class data.
        emp.eno = 77;
        emp.name = "Yash";
        emp.password = "confidential";
        objects_WriteRead(emp, fileName);

        Emp e = new Emp( );
        e.eno = 77;
        e.name = "Yash";
        e.password = "confidential";
        objects_WriteRead_External(e, fileName);

        /*String stubHost = "127.0.0.1";
        Integer anyFreePort = 7777;
        socketRead(anyFreePort); //Thread1
        socketWrite(emp, stubHost, anyFreePort); //Thread2*/

    }
    public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
        FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );
        objectOut.writeObject( obj );
        objectOut.close();
        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            FileInputStream fis = new FileInputStream( new File( serFilename ) );
            ObjectInputStream ois = new ObjectInputStream( fis );
            Object readObject;
            readObject = ois.readObject();
            String calssName = readObject.getClass().getName();
            System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException

            Employee emp = (Employee) readObject;
            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
        FileOutputStream fos = new FileOutputStream(new File( serFilename ));
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        obj.writeExternal( objectOut );
        objectOut.flush();

        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            // create a new instance and read the assign the contents from stream.
            Emp emp = new Emp();

            FileInputStream fis = new FileInputStream(new File( serFilename ));
            ObjectInputStream ois = new ObjectInputStream( fis );

            emp.readExternal(ois);

            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Serializable Example Over Network

Distributing object's state across different address spaces, either in different processes on the same computer, or even in multiple computers connected via a network, but which work together by sharing data and invoking methods.

/**
 * Creates a stream socket and connects it to the specified port number on the named host. 
 */
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
    try { // CLIENT - Stub[marshalling]
        Socket client = new Socket(stubHost, anyFreePort);
        ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
        out.writeObject(objectToSend);
        out.flush();
        client.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// Creates a server socket, bound to the specified port. 
public static void socketRead(  Integer anyFreePort ) {
    try { // SERVER - Stub[unmarshalling ]
        ServerSocket serverSocket = new ServerSocket( anyFreePort );
        System.out.println("Server serves on port and waiting for a client to communicate");
            /*System.in.read();
            System.in.read();*/

        Socket socket = serverSocket.accept();
        System.out.println("Client request to communicate on port server accepts it.");

        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Employee objectReceived = (Employee) in.readObject();
        System.out.println("Server Obj : "+ objectReceived.name );

        socket.close();
        serverSocket.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

@see


Daring to answer the 6-year-old question, adding just a very high-level understanding for people new to Java

What is Serialization?

Converting an object to bytes

What is Deserialization?

Converting bytes back to an object (Deserialization).

When is serialization used?

When we want to Persist the Object. When we want the object to exist beyond the lifetime of the JVM.

Real World Example:

ATM: When the account holder tries to withdraw money from the server through ATM, the account holder information like withdrawal details will be serialized and sent to the server where the details are deserialized and used to perform operations.

How serialization is performed in java.

  1. Implement java.io.Serializable interface (marker interface so no method to implement).

  2. Persist the object: Use java.io.ObjectOutputStream class, a filter stream which is a wrapper around a lower-level byte stream (to write Object to file systems or transfer a flattened object across a network wire and rebuilt on the other side).

    • writeObject(<<instance>>) - to write an object
    • readObject() - to read an serialized Object

Remember:

When you serialize an object, only the object's state will be saved, not the object's class file or methods.

When you serialized a 2-byte object, you see 51 bytes serialized file.

Steps how the object is serialized and de-serialized.

Answer for: How did it convert to 51 bytes file?

  • First writes the serialization stream magic data (STREAM_MAGIC= "AC ED" and STREAM_VERSION=version of the JVM).
  • Then it writes out the metadata of the class associated with an instance (length of the class, the name of the class, serialVersionUID).
  • Then it recursively writes out the metadata of the superclass until it finds java.lang.Object.
  • Then starts with the actual data associated with the instance.
  • Finally writes the data of objects associated with the instance starting from metadata to the actual content.

If you are interested in more in-depth information about Java Serialization please check this link.

Edit : One more good link to read.

This will answer a few frequent questions:

  1. How not to serialize any field in class.
    Ans: use transient keyword

  2. When child class is serialized does parent class get serialized?
    Ans: No, If a parent is not extending the Serializable interface parents field don't get serialized.

  3. When a parent is serialized does child class get serialized?
    Ans: Yes, by default child class also gets serialized.

  4. How to avoid child class from getting serialized?
    Ans: a. Override writeObject and readObject method and throw NotSerializableException.

    b. also you can mark all fields transient in child class.

  5. Some system-level classes such as Thread, OutputStream, and its subclasses, and Socket are not serializable.

I liked the way @OscarRyz presents. Although here i am continuing the story of serialization which was originally written by @amitgupta.

Even though knowing about the robot class structure and having serialized data Earth's scientist were not able to deserialize the data which can make robots working.

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

Mars's scientists were waiting for the complete payment. Once the payment was done Mars's scientists shared the serialversionUID with Earth's scientists. Earth's scientist set it to robot class and everything became fine.


Serialization is the process of saving an object in a storage medium (such as a file, or a memory buffer) or to transmit it over a network connection in binary form. The serialized objects are JVM independent and can be re-serialized by any JVM. In this case the "in memory" java objects state are converted into a byte stream. This type of the file can not be understood by the user. It is a special types of object i.e. reused by the JVM (Java Virtual Machine). This process of serializing an object is also called deflating or marshalling an object.

The object to be serialized must implement java.io.Serializable Interface. Default serialization mechanism for an object writes the class of the object, the class signature, and the values of all non-transient and non-static fields.

class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,

ObjectOutput interface extends the DataOutput interface and adds methods for serializing objects and writing bytes to the file. The ObjectOutputStream extends java.io.OutputStream and implements ObjectOutput interface. It serializes objects, arrays, and other values to a stream. Thus the constructor of ObjectOutputStream is written as:

ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));

Above code has been used to create the instance of the ObjectOutput class with the ObjectOutputStream( ) constructor which takes the instance of the FileOuputStream as a parameter.

The ObjectOutput interface is used by implementing the ObjectOutputStream class. The ObjectOutputStream is constructed to serialize the object.

Deserializing an Object in java

The opposite operation of the serialization is called deserialization i.e. to extract the data from a series of bytes is s known as deserialization which is also called inflating or unmarshalling.

ObjectInputStream extends java.io.InputStream and implements ObjectInput interface. It deserializes objects, arrays, and other values from an input stream. Thus the constructor of ObjectInputStream is written as:

ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));

Above code of the program creates the instance of the ObjectInputStream class to deserialize that file which had been serialized by the ObjectInputStream class. The above code creates the instance using the instance of the FileInputStream class which holds the specified file object which has to be deserialized because the ObjectInputStream() constructor needs the input stream.


Serialization is the process of turning a Java object into byte array and then back into object again with its preserved state. Useful for various things like sending objects over network or caching things to disk.

Read more from this short article which explains programming part of the process quite well and then move over to to Serializable javadoc. You may also be interested in reading this related question.


You can think of serialization as the process of converting an object instance into a sequence of bytes (which may be binary or not depending on the implementation).

It is very useful when you want to transmit one object data across the network, for instance from one JVM to another.

In Java, the serialization mechanism is built into the platform, but you need to implement the Serializable interface to make an object serializable.

You can also prevent some data in your object from being serialized by marking the attribute as transient.

Finally you can override the default mechanism, and provide your own; this may be suitable in some special cases. To do this, you use one of the hidden features in java.

It is important to notice that what gets serialized is the "value" of the object, or the contents, and not the class definition. Thus methods are not serialized.

Here is a very basic sample with comments to facilitate its reading:

import java.io.*;
import java.util.*;

// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  { 

        // Create a sample object, that contains the default values.
        SerializationSample instance = new SerializationSample();

        // The "ObjectOutputStream" class has the default 
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream( 
                               // By using "FileOutputStream" we will 
                               // Write it to a File in the file system
                               // It could have been a Socket to another 
                               // machine, a database, an in memory array, etc.
                               new FileOutputStream(new File("o.ser")));

        // do the magic  
        oos.writeObject( instance );
        // close the writing.
        oos.close();
    }
}

When we run this program, the file "o.ser" is created and we can see what happened behind.

If we change the value of: someInteger to, for example Integer.MAX_VALUE, we may compare the output to see what the difference is.

Here's a screenshot showing precisely that difference:

alt text

Can you spot the differences? ;)

There is an additional relevant field in Java serialization: The serialversionUID but I guess this is already too long to cover it.


I'll offer an analogy to potentially assist in solidifying the conceptual purpose/practicality of object serialization/deserialization.

I imagine object serialization/deserialization in the context of attempting to move an object through a storm drain. The object is essentially "decomposed" or serialized into more modular versions of itself - in this case, a series of bytes - in order to effectively be granted passage through a medium. In a computational sense, we could view the path traveled by the bytes through the storm drain as being akin to bytes traveling through a network. We're transmuting our object in order to conform to a more desirable mode of transportation, or format. The serialized object will typically be stored in a binary file which may later be read from, written to, or both.

Perhaps once our object is able to slip through the drain as a decomposed series of bytes, we may wish to store that representation of the object as binary data within a database or hard disk drive. The main takeaway though, is that with serialization/deserialization, we have the option to let our object remain in it's binary form after being serialized, or "retrieve" the object's original form by performing deserialization.


Return the file as an Object : http://www.tutorialspoint.com/java/java_serialization.htm

        import java.io.*;

        public class SerializeDemo
        {
           public static void main(String [] args)
           {
              Employee e = new Employee();
              e.name = "Reyan Ali";
              e.address = "Phokka Kuan, Ambehta Peer";
              e.SSN = 11122333;
              e.number = 101;

              try
              {
                 FileOutputStream fileOut =
                 new FileOutputStream("/tmp/employee.ser");
                 ObjectOutputStream out = new ObjectOutputStream(fileOut);
                 out.writeObject(e);
                 out.close();
                 fileOut.close();
                 System.out.printf("Serialized data is saved in /tmp/employee.ser");
              }catch(IOException i)
              {
                  i.printStackTrace();
              }
           }
        }

    import java.io.*;
    public class DeserializeDemo
    {
       public static void main(String [] args)
       {
          Employee e = null;
          try
          {
             FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn);
             e = (Employee) in.readObject();
             in.close();
             fileIn.close();
          }catch(IOException i)
          {
             i.printStackTrace();
             return;
          }catch(ClassNotFoundException c)
          {
             System.out.println("Employee class not found");
             c.printStackTrace();
             return;
          }
          System.out.println("Deserialized Employee...");
          System.out.println("Name: " + e.name);
          System.out.println("Address: " + e.address);
          System.out.println("SSN: " + e.SSN);
          System.out.println("Number: " + e.number);
        }
    }

Serialization means persisting objects in java. If you want to save the state of the object and want to rebuild the state later (may be in another JVM) serialization can be used.

Note that the properties of an object is only going to be saved. If you want to resurrect the object again you should have the class file, because the member variables only will be stored and not the member functions.

eg:

ObjectInputStream oos = new ObjectInputStream(                                 
                                 new FileInputStream(  new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();

The Searializable is a marker interface which marks that your class is serializable. Marker interface means that it is just an empty interface and using that interface will notify the JVM that this class can be made serializable.