Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Java - ObjectInputStream resolveObject(Object obj) method



Description

The Java ObjectInputStream resolveObject(Object obj) method allows trusted subclasses of ObjectInputStream to substitute one object for another during deserialization. Replacing objects is disabled until enableResolveObject is called. The enableResolveObject method checks that the stream requesting to resolve object can be trusted. Every reference to serializable objects is passed to resolveObject. To insure that the private state of objects is not unintentionally exposed only trusted streams may use resolveObject.

This method is called after an object has been read but before it is returned from readObject. The default resolveObject method just returns the same object.

When a subclass is replacing objects it must insure that the substituted object is compatible with every field where the reference will be stored. Objects whose type is not a subclass of the type of the field or array element abort the serialization by raising an exception and the object is not be stored.

Declaration

Following is the declaration for java.io.ObjectInputStream.resolveObject(Object obj) method.

protected Object resolveObject(Object obj)

Parameters

obj − object to be substituted.

Return Value

This method returns the substituted object.

Exception

  • IOException − Any of the usual Input/Output exceptions.

Example - Usage of ObjectInputStream resolveObject(Object obj) method

The following example shows the usage of Java ObjectInputStream resolveObject(Object obj) method.

ObjectInputStreamDemo.java

package com.tutorialspoint;

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

public class ObjectInputStreamDemo extends ObjectInputStream {

   public ObjectInputStreamDemo(InputStream in) throws IOException {
      super(in);
   }

   public static void main(String[] args) {
      String s = "Hello World";
      
      try {
         // create a new file with an ObjectOutputStream
         FileOutputStream out = new FileOutputStream("test.txt");
         ObjectOutputStream oout = new ObjectOutputStream(out);

         // write something in the file
         oout.writeUTF(s);
         oout.flush();

         // create an ObjectInputStream for the file we created before
         ObjectInputStreamDemo ois = new ObjectInputStreamDemo(new FileInputStream("test.txt"));

         // enable object resolving
         ois.enableResolveObject(true);

         // get the class for string and print the name
         System.out.println("" + ois.resolveObject(ois.readUTF()));
      } catch (Exception ex) {
         ex.printStackTrace();
      }
   }
}

Output

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

Hello World

Example - Replacing Null Values During Deserialization

The following example shows the usage of Java ObjectInputStream resolveObject(Object obj) method. • If the serialized object contains a null value, we replace it with a default object to prevent NullPointerException.

ObjectInputStreamDemo.java

package com.tutorialspoint;

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

public class ObjectInputStreamDemo {
   public static void main(String[] args) {
      // Serialize a Person object with a null reference
      try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
         oos.writeObject(null); // Writing a null object
         System.out.println("Serialized null object.");
      } catch (IOException e) {
         e.printStackTrace();
      }

      // Deserialize with resolveObject to replace null
      try (CustomObjectInputStream ois = new CustomObjectInputStream(new FileInputStream("person.ser"))) {
         Object obj = ois.readObject();
         if (obj == null) {
            System.out.println("Null detected. Replacing with default Person.");
            obj = new Person("Default Name");
         }
         System.out.println("Deserialized object: " + obj);
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
   static class CustomObjectInputStream extends ObjectInputStream {
      public CustomObjectInputStream(InputStream in) throws IOException {
         super(in);
         enableResolveObject(true);
      }

      @Override
      protected Object resolveObject(Object obj) throws IOException {
         System.out.println("resolveObject() called for: " + obj);
         if (obj == null) {
            System.out.println("Null detected. Replacing with default Person.");
            return new Person("Default Name");
         }
         return super.resolveObject(obj);
      }
   }
   static class Person implements Serializable {
      private static final long serialVersionUID = 1L;
      String name;

      public Person(String name) {
         this.name = name;
      }

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

Output

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

Serialized null object.
Null detected. Replacing with default Person.
Deserialized object: Person{name='Default Name'}

Explanation

  • We serialize a null object to person.ser.

  • During deserialization, resolveObject() detects null and replaces it with a default Person object.

  • The program avoids NullPointerException by providing a valid object.

Example - Replacing Old Objects with New Ones

The following example shows the usage of Java ObjectInputStream resolveObject(Object obj) method.

Scenario

  • Suppose we previously serialized an object of OldUser class.

  • The class is now renamed to NewUser, and we want to replace instances of OldUser with NewUser at runtime.

ObjectInputStreamDemo.java

package com.tutorialspoint;

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

public class ObjectInputStreamDemo {
   public static void main(String[] args) {
      // Step 1: Serialize OldUser
      try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"))) {
         OldUser oldUser = new OldUser("Alice");
         oos.writeObject(oldUser);
         System.out.println("Serialized OldUser object.");
      } catch (IOException e) {
         e.printStackTrace();
      }

      // Step 2: Deserialize and replace OldUser with NewUser
      try (CustomObjectInputStream ois = new CustomObjectInputStream(new FileInputStream("user.ser")) {
         }) {
         Object obj = ois.readObject();
         System.out.println("Deserialized object: " + obj);
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
   static class CustomObjectInputStream extends ObjectInputStream {
      public CustomObjectInputStream(InputStream in) throws IOException {
         super(in);
         enableResolveObject(true); 
      }

      @Override
      protected Object resolveObject(Object obj) throws IOException {
         System.out.println("resolveObject() called for: " + obj);
         if (obj instanceof OldUser) {
            OldUser oldUser = (OldUser) obj;
            System.out.println("Replacing OldUser with NewUser.");
            return new NewUser(oldUser.username);
         }
         return super.resolveObject(obj);
      }
   }

   static class OldUser implements Serializable {
      private static final long serialVersionUID = 1L;
      String username;

      public OldUser(String username) {
         this.username = username;
      }

      @Override
      public String toString() {
         return "OldUser{username='" + username + "'}";
      }
   }
   
   static class NewUser implements Serializable {
      private static final long serialVersionUID = 2L;
      String username;
      boolean isActive;

      public NewUser(String username) {
         this.username = username;
         this.isActive = true; // New field added
      }

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

Output

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

Serialized OldUser object.
resolveObject() called for: Alice
resolveObject() called for: OldUser{username='Alice'}
Replacing OldUser with NewUser.
Deserialized object: NewUser{username='Alice', isActive=true}

Explanation

  • We first serialize an instance of OldUser.

  • When deserializing, resolveObject() detects OldUser and replaces it with NewUser.

java_io_objectinputstream.htm
Advertisements