Java - ObjectInputStream defaultReadObject() method



Description

The Java ObjectInputStream defaultReadObject() restores the default serialization state of an object. It is typically used inside the readObject(ObjectInputStream ois) method of a class implementing Serializable. defaultReadObject() reads and restores non-transient fields of the object. It must be called inside readObject(ObjectInputStream ois). Transient fields are not restored (they must be handled separately).

Declaration

Following is the declaration for java.io.ObjectInputStream.defaultReadObject() method −

public void defaultReadObject()

Parameters

NA

Return Value

This method does not return a value.

Exception

  • ClassNotFoundException − if the class of a serialized object could not be found.

  • IOException − if an I/O error occurs.

  • NotActiveException − if the stream is not currently reading objects.

Example - Using defaultReadObject() for Basic Serialization

The following example shows the usage of Java ObjectInputStream defaultReadObject() method. This example demonstrates default serialization using defaultReadObject()

ObjectInputStreamDemo.java

package com.tutorialspoint;

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

class Person implements Serializable {
   private static final long serialVersionUID = 1L;
   String name;
   int age;

   public Person(String name, int age) {
      this.name = name;
      this.age = age;
   }
   
   private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
      ois.defaultReadObject(); // Restores default serialized fields
   }

   @Override
   public String toString() {
      return "Person{name='" + name + "', age=" + age + "}";
   }
}

public class ObjectInputStreamDemo {
   public static void main(String[] args) {
      try {
         // Serialize object
         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"));
         oos.writeObject(new Person("Alice", 30));
         oos.close();

         // Deserialize object
         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"));
         Person person = (Person) ois.readObject();
         ois.close();

         System.out.println("Deserialized Object: " + person);
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
}

Output

Let us compile and run the above program, this will produce the following result−

Deserialized Object: Person{name='Alice', age=30}

Explanation

  • The Person object is serialized and written to person.dat.

  • During deserialization, defaultReadObject() restores the name and age fields.

  • The deserialized object is printed correctly.

Example - Handling Transient Fields with defaultReadObject()

The following example shows the usage of Java ObjectInputStream defaultReadObject() method. This example shows that transient fields are not restored unless handled manually.

ObjectInputStreamDemo.java

package com.tutorialspoint;

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

class User implements Serializable {
   private static final long serialVersionUID = 1L;
   String username;
   transient String password; // Transient field

   public User(String username, String password) {
      this.username = username;
      this.password = password;
   }

   private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
      ois.defaultReadObject(); // Reads non-transient fields
   }

   @Override
   public String toString() {
      return "User{username='" + username + "', password='" + password + "'}";
   }
}

public class ObjectInputStreamDemo {
   public static void main(String[] args) {
      try {
         // Serialize object
         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"));
         oos.writeObject(new User("john_doe", "secure123"));
         oos.close();

         // Deserialize object
         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"));
         User user = (User) ois.readObject();
         ois.close();

         System.out.println("Deserialized Object: " + user);
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
}

Output

Let us compile and run the above program, this will produce the following result−

Deserialized Object: User{username='john_doe', password='null'}

Explanation

  • The password field is declared transient, so it is not serialized.

  • During deserialization, defaultReadObject() restores only non-transient fields (username).

  • The password field is null after deserialization.

Example - Restoring Transient Fields After defaultReadObject()

The following example shows the usage of Java ObjectInputStream defaultReadObject() method. This example shows how to manually restore a transient field during deserialization.

ObjectInputStreamDemo.java

package com.tutorialspoint;

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

class SecureUser implements Serializable {
   private static final long serialVersionUID = 1L;
   String username;
   transient String password;

   public SecureUser(String username, String password) {
      this.username = username;
      this.password = password;
   }

   private void writeObject(ObjectOutputStream oos) throws IOException {
      oos.defaultWriteObject(); // Serialize non-transient fields
      oos.writeObject(password); // Manually serialize the password
   }

   private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
      ois.defaultReadObject(); // Restore non-transient fields
      password = (String) ois.readObject(); // Manually restore transient field
   }

   @Override
   public String toString() {
      return "SecureUser{username='" + username + "', password='" + password + "'}";
   }
}

public class ObjectInputStreamDemo {
   public static void main(String[] args) {
      try {
         // Serialize object
         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("secureUser.dat"));
         oos.writeObject(new SecureUser("john_doe", "secure123"));
         oos.close();

         // Deserialize object
         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("secureUser.dat"));
         SecureUser user = (SecureUser) ois.readObject();
         ois.close();

         System.out.println("Deserialized Object: " + user);
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
}

Output

Let us compile and run the above program, this will produce the following result−

Deserialized Object: SecureUser{username='john_doe', password='secure123'}

Explanation

  • Before serialization, defaultWriteObject() saves username, and password is written manually.

  • During deserialization, defaultReadObject() restores username, and password is read separately.

  • Unlike the previous example, the password is successfully restored.

java_io_objectinputstream.htm
Advertisements