CodeGym /Courses /JAVA 25 SELF /ObjectOutputStream, ObjectInputStream: working with strea...

ObjectOutputStream, ObjectInputStream: working with streams

JAVA 25 SELF
Level 42 , Lesson 3
Available

1. Introduction

In Java, serialization works only with those objects that have explicitly allowed it. For this, the class must implement the special interface — java.io.Serializable.

import java.io.Serializable;

public class Person implements Serializable {
    // Fields, constructors, methods
}

Serializable is a marker interface: it has no methods; it simply tells the JVM — “this class can be serialized, don’t worry!”. If you try to serialize an object of a class that does not implement Serializable, you will get a NotSerializableException. Even if at least one field (or a nested object) is not serializable, serialization will not work.

ObjectOutputStream and ObjectInputStream

  • ObjectOutputStream — a class that writes objects to a stream (for example, to a file or over the network).
  • ObjectInputStream — a class that reads objects from a stream.

They work as a pair: one serializes the object, the other — deserializes it.

Key methods

  • writeObject(Object obj) — serializes the object and writes it to the stream.
  • readObject() — reads an object from the stream, deserializes it, and returns it.

Important: both classes work on top of regular I/O streams (OutputStream and InputStream). Most often they’re used together with file streams — FileOutputStream and FileInputStream, but they can also be used with network streams.

2. Serialization example

Let’s write a simple example: serialize and deserialize an object of the Person class.

Step 1. Define the class

import java.io.Serializable;

public class Person implements Serializable {
    private String name;
    private int age;
    // The transient field will not be serialized
    private transient String secret;

    public Person(String name, int age, String secret) {
        this.name = name;
        this.age = age;
        this.secret = secret;
    }

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

Step 2. Serialize an object to a file

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class SerializeDemo {
    public static void main(String[] args) throws Exception {
        Person person = new Person("Alice", 30, "likes pizza");

        // Create a stream for writing to a file
        FileOutputStream fileOut = new FileOutputStream("person.bin");
        ObjectOutputStream out = new ObjectOutputStream(fileOut);

        // Save the object
        out.writeObject(person);

        // Close the streams
        out.close();
        fileOut.close();

        System.out.println("Object serialized to file person.bin");
    }
}

Step 3. Deserialize an object from a file

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class DeserializeDemo {
    public static void main(String[] args) throws Exception {
        // Open a stream for reading from the file
        FileInputStream fileIn = new FileInputStream("person.bin");
        ObjectInputStream in = new ObjectInputStream(fileIn);

        // Restore the object
        Person person = (Person) in.readObject();

        in.close();
        fileIn.close();

        System.out.println("Object deserialized: " + person);
    }
}

Expected output

Object serialized to file person.bin
Object deserialized: Person{name='Alice', age=30, secret='null'}

Attention! The transient field is not serialized. After deserialization it will be null. This is important for temporary or sensitive data.

3. Constraints and specifics

All fields must be serializable

If a class has fields that themselves do not implement Serializable (or contain such objects), serialization will fail. For example, fields of type Thread or Socket cannot be made serializable as-is.

Static and transient fields

  • Static fields (static) are not serialized: they belong to the class, not to a specific object.
  • transient fields — those marked as transient are explicitly excluded from serialization and after restoration get default values (null, 0, etc.).

Exceptions

  • An attempt to serialize an object that does not implement Serializable results in NotSerializableException.
  • During deserialization, errors are possible: file not found, class mismatch, corrupted data, etc.

Class versions

If you change the structure of a class after serialization (for example, add/remove fields), during deserialization an InvalidClassException may occur. A special field serialVersionUID is used for version control (more on it in a later lecture).

4. Practice: serialization and deserialization of an object to a file

Suppose we have a Person class, and we want to save a list of people to a file and read it back.

Person class (serializable)

import java.io.Serializable;

public class Person implements Serializable {
    private String name;
    private int age;
    private transient String secret; // will not be serialized

    public Person(String name, int age, String secret) {
        this.name = name;
        this.age = age;
        this.secret = secret;
    }

    @Override
    public String toString() {
        return name + " (" + age + "), secret: " + secret;
    }
}

Serializing a list of people

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class SerializeListDemo {
    public static void main(String[] args) throws Exception {
        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 30, "likes pizza"));
        people.add(new Person("Bob", 25, "hates broccoli"));

        FileOutputStream fileOut = new FileOutputStream("people.bin");
        ObjectOutputStream out = new ObjectOutputStream(fileOut);

        // Save the list
        out.writeObject(people);

        out.close();
        fileOut.close();

        System.out.println("The list of people has been serialized.");
    }
}

Deserializing a list of people

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.List;

public class DeserializeListDemo {
    public static void main(String[] args) throws Exception {
        FileInputStream fileIn = new FileInputStream("people.bin");
        ObjectInputStream in = new ObjectInputStream(fileIn);

        // Restore the list
        List<Person> people = (List<Person>) in.readObject();

        in.close();
        fileIn.close();

        for (Person p : people) {
            System.out.println(p);
        }
    }
}

Result:

Alice (30), secret: null
Bob (25), secret: null

5. Common mistakes

Error #1: The class does not implement Serializable. If you forget to add implements Serializable, attempting serialization will result in NotSerializableException. This is the most common and simplest mistake.

Error #2: Non-serializable field. If an object contains a field that is not serializable (for example, Thread, Socket, or any other type without Serializable), serialization will fail. Mark such fields as transient or make them serializable.

Error #3: Changing the class structure. If an object is serialized and later the class is changed (fields added/removed), an InvalidClassException may occur when reading. Specify serialVersionUID to keep versioning stable.

Error #4: Attempting to serialize static fields. Fields with the static modifier are not serialized. After deserialization, their values will be whatever the class currently defines by default, not what they were at serialization time.

Error #5: Streams not closed. If you don’t close streams after use, you can end up with a corrupted file or a resource leak. Use try-with-resources or close streams explicitly.

Error #6: Class mismatch. If a class was renamed or moved to another package, deserialization will not work — an exact match of the class name and package stored in the stream is required.

1
Task
JAVA 25 SELF, level 42, lesson 3
Locked
Serializing a simple object
Serializing a simple object
1
Task
JAVA 25 SELF, level 42, lesson 3
Locked
transient field and serialization
transient field and serialization
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION