Thanks to visit codestin.com
Credit goes to www.tutorialspoint.com

Java - ObjectInputStream readFields() method



Description

The Java ObjectInputStream readFields() method reads the persistent fields of a serialized object. readFields() returns an ObjectInputStream.GetField object, which allows retrieving individual fields.

Declaration

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

public ObjectInputStream.GetField readFields()

Parameters

NA

Return Value

This method returns the GetField object representing the persistent fields of the object being deserialized.

Exception

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

  • IOException − If an I/O error has occurred.

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

Example - Usage of ObjectInputStream readFields() method

The following example shows the usage of Java ObjectInputStream readFields() method.

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;

public class ObjectInputStreamDemo {
   public static void main(String[] args) {
      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(new Example());
         oout.flush();

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

         // read the object and print the string
         Example a = (Example) ois.readObject();

         // print the string that is in Example class
         System.out.println("" + a.s);

      } catch (Exception ex) {
         ex.printStackTrace();
      }
   }

   static class Example implements Serializable {
      String s = "Hello World!";

      private String readObject(ObjectInputStream in) 
         throws IOException, ClassNotFoundException {

         // call readFields in readObject
         ObjectInputStream.GetField gf = in.readFields();

         // save the string and return it
         return (String) gf.get("s", null);
      }
   }
}

Output

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

Hello World!

Example - Reading Fields along with Missing Fields

The following example shows the usage of Java ObjectInputStream readFields() method. This example demonstrates how readFields() can handle missing fields gracefully.

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;

public class ObjectInputStreamDemo {

   public static void main(String[] args) {
      try {
         // Serialize Employee object (older version might not have 'salary' field)
         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("employee.dat"));
         oos.writeObject(new Employee("Alice", 30, 8000.0));
         oos.close();

         // Deserialize Employee object (simulate reading an old version without 'salary')
         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("employee.dat"));
         Employee emp = (Employee) ois.readObject();
         ois.close();

         System.out.println("Deserialized Employee: " + emp);
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
   static class Employee implements Serializable {
      private static final long serialVersionUID = 1L;
      String name;
      int age;
      double salary; // New field, not present in old serialized objects

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

      private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
         ObjectInputStream.GetField fields = ois.readFields(); // Read serialized fields
         name = (String) fields.get("name", "Unknown"); // Default if missing
         age = fields.get("age", 0); // Default if missing
         salary = fields.get("salary", 5000.0); // Default value for missing salary field
      }

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

Output

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

Deserialized Employee: Employee{name='Alice', age=30, salary=8000.0}

Explanation

  • Serializes an Employee object (in older versions, the salary field might be missing).

  • Reads fields using readFields().

  • Assigns default values ("Unknown" for name, 0 for age, 5000.0 for salary) if missing.

Example - Handling Extra Fields in a New Version of a Class

The following example shows the usage of Java ObjectInputStream readFields() method. This example handles additional fields in a new version of a class, ensuring backward compatibility.

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;

public class ObjectInputStreamDemo {
   public static void main(String[] args) {
      try {
         // Serialize Product object (simulating older version)
         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("product.dat"));
         oos.writeObject(new Product("Laptop", 1200.99, "IdeaPad")); // No 'category' field
         oos.close();

         // Deserialize using the new Product class
         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("product.dat"));
         Product product = (Product) ois.readObject();
         ois.close();

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

   static class Product implements Serializable {
      private static final long serialVersionUID = 1L;
      String name;
      double price;
      String category; 

      public Product(String name, double price, String category) {
         this.name = name;
         this.price = price;
         this.category = category;
      }

      private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
         ObjectInputStream.GetField fields = ois.readFields(); // Read serialized fields
         name = (String) fields.get("name", "Unknown");
         price = fields.get("price", 0.0);
         category = (String)fields.get("category", "Uncategorized"); // Default value for missing category field
      }

      @Override
      public String toString() {
         return "Product{name='" + name + "', price=" + price + ", category='" + category + "'}";
      }
   }
}

Output

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

Deserialized Product: Product{name='Laptop', price=1200.99, category='IdeaPad'}

Explanation

  • Serializes an OldProduct object, which lacks the category field.

  • Reads fields using readFields(), allowing retrieval of old values.

  • Assigns "Uncategorized" as a default for missing category.

java_io_objectinputstream.htm
Advertisements