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

Java - ObjectInputStream readObjectOverride() method



Description

The Java ObjectInputStream readObjectOverride() method is called by trusted subclasses of ObjectOutputStream that constructed ObjectOutputStream using the protected no-arg constructor. The subclass is expected to provide an override method with the modifier "final".

Declaration

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

protected Object readObjectOverride()

Parameters

NA

Return Value

This method returns the object read from the stream.

Exception

  • ClassNotFoundException − Class of a serialized object cannot be found.

  • OptionalDataException − Primitive data was found in the stream instead of objects.

  • IOException − If I/O errors occurred while reading from the underlying stream.

Example - Usage of ObjectInputStream readObjectOverride() method

The following example shows the usage of Java ObjectInputStream readObjectOverride() 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.writeObject(s);
         oout.flush();

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

         // read and print an object and cast it as string
         System.out.println("" + (String)ois.readObjectOverride());
      } catch (Exception ex) {
         ex.printStackTrace();
      }
   }
}

Output

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

null

Example - Overriding readObjectOverride() in a Custom Stream Class

The following example shows the usage of Java ObjectInputStream readObjectOverride() method. This example creates a custom ObjectInputStream subclass that overrides readObjectOverride() to add custom logging when deserializing objects.

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;

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;
   }

   public void display() {
      System.out.println("Name: " + name + ", Age: " + age);
   }
}

// Custom ObjectInputStream class
class CustomObjectInputStream extends ObjectInputStream {
   public CustomObjectInputStream(InputStream in) throws IOException {
      super(in);
   }

   @Override
   protected Object readObjectOverride() throws IOException, ClassNotFoundException {
      System.out.println("Custom deserialization in progress...");
      return super.readObject();
   }
}

public class ObjectInputStreamDemo {
   public static void main(String[] args) {
      String filename = "personData.ser";

      // Writing an object to a file
      try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
         Person person = new Person("Alice", 30);
         oos.writeObject(person);
         System.out.println("Object written.");
      } catch (IOException e) {
         e.printStackTrace();
      }

      // Reading the object using custom ObjectInputStream
      try (CustomObjectInputStream cois = new CustomObjectInputStream(new FileInputStream(filename))) {
         Person readPerson = (Person) cois.readObject();
         System.out.println("Object read:");
         readPerson.display();
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
}

Output

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

Object written.
Object read:
Name: Alice, Age: 30

Explanation

  • A CustomObjectInputStream class is created, extending ObjectInputStream.

  • The readObjectOverride() method is overridden to print a log message before calling super.readObject().

  • A Person object is serialized and deserialized using this custom stream.

  • The overridden method provides a logging mechanism before object deserialization.

Example - Filtering Allowed Classes During Deserialization

The following example shows the usage of Java ObjectInputStream readObjectOverride() method. This example restricts which classes can be deserialized using readObjectOverride().

ObjectInputStreamDemo.java

package com.tutorialspoint;

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

// A sample class that implements Serializable
class Employee implements Serializable {
   private static final long serialVersionUID = 1L;
   String name;
   double salary;

   public Employee(String name, double salary) {
      this.name = name;
      this.salary = salary;
   }

   public void display() {
      System.out.println("Employee Name: " + name + ", Salary: " + salary);
   }
}

// Custom ObjectInputStream that restricts allowed classes
class RestrictedObjectInputStream extends ObjectInputStream {
   public RestrictedObjectInputStream(InputStream in) throws IOException {
      super(in);
   }

   @Override
   protected Object readObjectOverride() throws IOException, ClassNotFoundException {
      Object obj = super.readObject();
      if (!(obj instanceof Employee)) {
         throw new InvalidClassException("Unauthorized class deserialization attempt!");
      }
      return obj;
   }
}

public class ObjectInputStreamDemo {
   public static void main(String[] args) {
      String filename = "employeeData.ser";

      // Writing an Employee object to a file
      try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
         Employee emp = new Employee("John Doe", 75000);
         oos.writeObject(emp);
         System.out.println("Employee object written.");
      } catch (IOException e) {
         e.printStackTrace();
      }

      // Reading the object using RestrictedObjectInputStream
      try (RestrictedObjectInputStream rois = new RestrictedObjectInputStream(new FileInputStream(filename))) {
         Employee readEmp = (Employee) rois.readObject();
         System.out.println("Employee object read:");
         readEmp.display();
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
}

Output

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

Employee object written.
Employee object read:
Employee Name: John Doe, Salary: 75000.0

Explanation

  • A RestrictedObjectInputStream class is created by extending ObjectInputStream.

  • The readObjectOverride() method is overridden to check if the deserialized object is an instance of Employee.

  • If an unauthorized class is deserialized, an InvalidClassException is thrown.

  • This ensures only Employee objects are allowed to be deserialized.

java_io_objectinputstream.htm
Advertisements