Java ObjectInput Interface
Last modified: April 16, 2025
The java.io.ObjectInput
interface extends DataInput
and
provides functionality for reading objects and primitive data types. It is used
primarily for object deserialization in Java's serialization mechanism.
ObjectInput
is implemented by classes like ObjectInputStream
that perform deserialization of objects. The interface provides methods to read
objects, primitive types, and arrays from an input source. It also supports
reading bytes and skipping data.
ObjectInput Interface Overview
The ObjectInput
interface combines object reading with primitive data
reading capabilities. Key methods include object deserialization, primitive type
reading, and stream control operations. All methods can throw IOException for
I/O errors.
public interface ObjectInput extends DataInput, AutoCloseable { Object readObject() throws ClassNotFoundException, IOException; int read() throws IOException; int read(byte[] b) throws IOException; int read(byte[] b, int off, int len) throws IOException; long skip(long n) throws IOException; int available() throws IOException; void close() throws IOException; }
The code above shows the core methods of ObjectInput
. The interface
extends DataInput
which provides primitive reading methods. The
readObject
method is the primary method for deserializing objects.
Basic Object Deserialization
The most fundamental use of ObjectInput
is deserializing objects.
This requires the object's class to implement Serializable
. The
readObject
method reads and reconstructs the serialized object.
import java.io.FileInputStream; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.IOException; class Person implements java.io.Serializable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } } public class Main { public static void main(String[] args) { try (ObjectInput in = new ObjectInputStream( new FileInputStream("person.ser"))) { Person p = (Person) in.readObject(); System.out.println("Deserialized Person: " + p); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } }
This example demonstrates basic object deserialization. The Person
class must implement Serializable
. The readObject
method reconstructs the object from the serialized data. The cast is necessary
as readObject
returns Object
.
Reading Primitive Types
ObjectInput
inherits primitive type reading methods from
DataInput
. These include methods for reading all Java primitive
types. The methods read data in network byte order (big-endian).
import java.io.FileInputStream; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (ObjectInput in = new ObjectInputStream( new FileInputStream("primitives.dat"))) { boolean bool = in.readBoolean(); byte b = in.readByte(); char c = in.readChar(); short s = in.readShort(); int i = in.readInt(); long l = in.readLong(); float f = in.readFloat(); double d = in.readDouble(); System.out.println("Boolean: " + bool); System.out.println("Byte: " + b); System.out.println("Char: " + c); System.out.println("Short: " + s); System.out.println("Int: " + i); System.out.println("Long: " + l); System.out.println("Float: " + f); System.out.println("Double: " + d); } catch (IOException e) { e.printStackTrace(); } } }
This example shows reading primitive types from an ObjectInput
stream. The data must be written in the same order it's read. Each method reads
the appropriate number of bytes for the type. The stream must contain enough
data for all reads.
Reading Byte Arrays
ObjectInput
provides methods for reading byte arrays. The
read(byte[])
method attempts to fill the entire array. The
read(byte[], int, int)
method reads into a portion of the array.
import java.io.FileInputStream; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.IOException; import java.util.Arrays; public class Main { public static void main(String[] args) { try (ObjectInput in = new ObjectInputStream( new FileInputStream("bytes.dat"))) { // Read full array byte[] buffer1 = new byte[10]; int bytesRead1 = in.read(buffer1); System.out.println("Read " + bytesRead1 + " bytes: " + Arrays.toString(buffer1)); // Read partial array byte[] buffer2 = new byte[20]; int bytesRead2 = in.read(buffer2, 5, 10); System.out.println("Read " + bytesRead2 + " bytes into offset 5: " + Arrays.toString(buffer2)); } catch (IOException e) { e.printStackTrace(); } } }
This example demonstrates reading byte arrays. The first read attempts to fill the entire 10-byte array. The second read puts 10 bytes starting at offset 5 in a 20-byte array. Both methods return the number of bytes actually read.
Skipping Bytes and Checking Availability
The skip
method allows skipping bytes in the input stream. The
available
method estimates bytes that can be read without blocking.
These are useful for stream navigation and status checking.
import java.io.ByteArrayInputStream; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { byte[] data = new byte[100]; for (int i = 0; i < data.length; i++) { data[i] = (byte) i; } try (ObjectInput in = new ObjectInputStream( new ByteArrayInputStream(data))) { System.out.println("Initially available: " + in.available()); // Skip first 20 bytes long skipped = in.skip(20); System.out.println("Skipped " + skipped + " bytes"); // Read next byte int nextByte = in.read(); System.out.println("Next byte: " + nextByte); System.out.println("Now available: " + in.available()); // Skip remaining skipped = in.skip(100); System.out.println("Skipped " + skipped + " more bytes"); System.out.println("Final available: " + in.available()); } catch (IOException e) { e.printStackTrace(); } } }
This example shows skipping bytes and checking availability. The skip
method may skip fewer bytes than requested. The available
method
returns the remaining bytes. After skipping all bytes, available
returns 0.
Reading Multiple Objects
ObjectInput
can read multiple objects sequentially from a stream.
Each readObject
call reads the next object. The objects must be
read in the same order they were written.
import java.io.FileInputStream; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.IOException; class Product implements java.io.Serializable { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } @Override public String toString() { return String.format("Product{name='%s', price=%.2f}", name, price); } } public class Main { public static void main(String[] args) { try (ObjectInput in = new ObjectInputStream( new FileInputStream("products.ser"))) { // Read first object Product p1 = (Product) in.readObject(); System.out.println("First product: " + p1); // Read second object Product p2 = (Product) in.readObject(); System.out.println("Second product: " + p2); // Read primitive between objects int count = in.readInt(); System.out.println("Product count: " + count); // Read third object Product p3 = (Product) in.readObject(); System.out.println("Third product: " + p3); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } }
This example reads multiple objects interspersed with primitive data. The objects and primitives must be read in the exact order they were written. Attempting to read objects in the wrong order will cause exceptions. The stream maintains the serialization graph structure.
Source
Java ObjectInput Interface Documentation
In this article, we've covered the essential methods and features of the Java ObjectInput interface. Understanding these concepts is crucial for working with object serialization and deserialization in Java applications.
Author
List all Java tutorials.