Provide Best Programming Tutorials

The Serializable Interface

Not every object can be written to an output stream. Objects that can be so written are said to be serializable. A serializable object is an instance of the java.io.Serializable interface, so the object’s class must implement the Serializable interface.

The Serializable interface is a marker interface. Since it has no methods, you don’t need to add additional code in your class that implements Serializable interface. Implementing this interface enables the Java serialization mechanism to automate the process of storing objects and arrays.

To appreciate this automation feature, consider what you otherwise need to do in order to store an object. Suppose that you wish to store an ArrayList object. To do this, you need to store all the elements in the list. Each element is an object that may contain other objects. As you can see, this would be a very tedious process. Fortunately, you don’t have to go through it manually. Java provides a built-in mechanism to automate the process of writing objects. This process is referred to as object serialization, which is implemented in ObjectOutputStream.In contrast, the process of reading objects is referred to as object deserialization, which is implemented in ObjectInputStream.

Many classes in the Java API implement Serializable. All the wrapper classes for primitivetype values, java.math.BigInteger , java.math.BigDecimal , java.lang.String ,java.lang.StringBuilder , java.lang.StringBuffer, java.util.Date, and java.util.ArrayList implement java.io.Serializable. Attempting to store an object that does not support the Serializable interface would cause a NotSerializableException.

When a serializable object is stored, the class of the object is encoded; this includes the class name and the signature of the class, the values of the object’s instance variables, and the closure of any other objects referenced by the object. The values of the object’s static variables are not stored.

Nonserializable fields

If an object is an instance of Serializable but contains non-serializable instance data fields, can it be serialized? The answer is no. To enable the object to be serialized, mark these data fields with the transient keyword to tell the JVM to ignore them when writing the object to an object stream. Consider the following class:

public class C implements java.io.Serializable {
    private int v1;
    private static double v2;
    private transient A v3 = new A();
}

class A { } // A is not serializable

When an object of the C class is serialized, only variable v1 is serialized. Variable v2 is not serialized because it is a static variable, and variable v3 is not serialized because it is marked transient. If v3 were not marked transient, a java.io.NotSerializableException would occur, because class A does not implements Serializable interface.Of course you can also let class A implements Serializable interface thus you don’t need transient anymore.

Duplicate objects

If an object is written to an object stream more than once, will it be stored in multiple copies? No, it will not. When an object is written for the first time, a serial number is created for it. The JVM writes the complete contents of the object along with the serial number into the object stream. After the first time, only the serial number is stored if the same object is written again. When the objects are read back, their references are the same since only one object is actually created in the memory.

Serializing Arrays

An array is serializable if all its elements are serializable. An entire array can be saved into a file using writeObject and later can be restored using readObject.

The program below stores an array of five int values and an array of three strings, and reads them back to display on the console.

import java.io.*;

public class TestObjectStreamForArray {
  public static void main(String[] args)
      throws ClassNotFoundException, IOException {
    int[] numbers = {1, 2, 3, 4, 5};
    String[] strings = {"John", "Susan", "Kim"};

    try ( // Create an output stream for file array.dat
      ObjectOutputStream output = new ObjectOutputStream(new 
        FileOutputStream("array.dat", true));
    ) {
      // Write arrays to the object output stream
      output.writeObject(numbers);
      output.writeObject(strings);
    }

    try ( // Create an input stream for file array.dat
      ObjectInputStream input =
        new ObjectInputStream(new FileInputStream("array.dat"));
    ) {
      int[] newNumbers = (int[])(input.readObject());
      String[] newStrings = (String[])(input.readObject());
  
      // Display arrays
      for (int i = 0; i < newNumbers.length; i++)
        System.out.print(newNumbers[i] + " ");
      System.out.println();
  
      for (int i = 0; i < newStrings.length; i++)
        System.out.print(newStrings[i] + " ");
    }
  }
}

Lines 14–15 write two arrays into file array.dat . Lines 22–23 read two arrays back in the same order they were written. Since readObject() returns Object , casting is used to cast the objects into int[] and String[] .

 

 

 

 

 

 

Leave a Reply

Close Menu