CodeToConcept
About

java

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

Sample Question

Think it through, then check the tutorial.

CodeToConcept

Quickly learn through simple, structured, and practical coding tutorials. Build your confidence from step zero to real-world experience.

© 2026 CodeToConcept. All rights reserved.

Quick Links

AboutTutorials

Tutorials

JavaHTMLCSS

Support

Privacy PolicyTerms of ServiceContact
GitHubTwitterYouTube

Java Serialization and Deserialization

Run each complete program separately. Its required helper classes and imports are included in the same code block. Short syntax fragments explain individual operations.

Java object serialization writes supported object state to a stream and can read it back later. It follows references within that state rather than simply saving a printed object description. Compatibility, skipped fields, and the trust of the input all affect whether it is suitable.

Deserialization is the reverse process. It converts the stored byte data back into an object.

Serialization is useful when an application needs to:

  • Save an object's state to a file
  • Transfer an object between applications
  • Send objects over a network
  • Cache objects
  • Persist temporary application state
  • Store multiple objects for later use

The basic concept is:

Java Object
     |
     | Serialization
     v
Byte Stream
     |
     | Deserialization
     v
Java Object

1. What is Serialization?

Serialization is the process of converting a Java object's state into a byte stream.

The byte stream can then be:

  • Stored in a file
  • Sent over a network
  • Stored temporarily
  • Transferred between systems

For example, suppose we have a Student object:

Student student = new Student("Rahul", 101, 85);

Serialization converts the object's state into bytes.

Student Object
      |
      v
Serialization
      |
      v
Byte Stream

2. What is Deserialization?

Deserialization is the process of converting the serialized byte stream back into a Java object.

Byte Stream
     |
     v
Deserialization
     |
     v
Student Object

After deserialization, we can access the object's data again.

3. Serialization and Deserialization Difference

SerializationDeserialization
Converts object into byte streamConverts byte stream into object
Object → bytesBytes → object
Used for storing/transferring object stateUsed for retrieving object state
Uses ObjectOutputStreamUses ObjectInputStream

4. Serializable Interface

To serialize an object using Java's standard object serialization mechanism, the class generally implements the Serializable interface.

The interface is available in:

java.io.Serializable

Example

import java.io.Serializable;
 
class Student implements Serializable {
 
    int id;
    String name;
}

Serializable is a marker interface.

A marker interface does not require the class to implement any methods.

5. Simple Serialization Example

Let's create a Student class.

import java.io.Serializable;
 
class Student implements Serializable {
 
    int id;
    String name;
 
    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

Now we can serialize the object.

import java.io.Serializable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
class Student implements Serializable {
 
    int id;
    String name;
 
    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Student student = new Student(101, "Rahul");
 
        try {
            FileOutputStream file =
                    new FileOutputStream("student.ser");
 
            ObjectOutputStream output =
                    new ObjectOutputStream(file);
 
            output.writeObject(student);
 
            output.close();
            file.close();
 
            System.out.println("Object serialized successfully.");
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Output

Object serialized successfully.

A file named:

student.ser

is created.

The .ser extension is commonly used for serialized object files, although Java does not require a particular extension.

6. Understanding ObjectOutputStream

The ObjectOutputStream class is responsible for writing Java objects to an output stream.

For example:

ObjectOutputStream output =
        new ObjectOutputStream(file);

Then:

output.writeObject(student);

writes the object into the stream.

The general structure is:

Object
   |
   v
ObjectOutputStream
   |
   v
Output Stream
   |
   v
File

7. Deserializing an Object

After serializing the object, we can read it back using ObjectInputStream.

Example

import java.io.Serializable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
class Student implements Serializable {
 
    int id;
    String name;
 
    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        try {
            FileInputStream file =
                    new FileInputStream("student.ser");
 
            ObjectInputStream input =
                    new ObjectInputStream(file);
 
            Student student =
                    (Student) input.readObject();
 
            input.close();
            file.close();
 
            System.out.println("ID: " + student.id);
            System.out.println("Name: " + student.name);
 
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Output

ID: 101
Name: Rahul

The serialized byte data has been converted back into a Student object.

8. Complete Serialization and Deserialization Example

Here is a complete example.

import java.io.*;
 
class Student implements Serializable {
 
    int id;
    String name;
    double marks;
 
    Student(int id, String name, double marks) {
        this.id = id;
        this.name = name;
        this.marks = marks;
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Student student =
                new Student(101, "Rahul", 85.5);
 
        // Serialization
        try (ObjectOutputStream output =
                     new ObjectOutputStream(
                             new FileOutputStream("student.ser"))) {
 
            output.writeObject(student);
 
            System.out.println("Serialization completed.");
 
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        // Deserialization
        try (ObjectInputStream input =
                     new ObjectInputStream(
                             new FileInputStream("student.ser"))) {
 
            Student result =
                    (Student) input.readObject();
 
            System.out.println("Deserialization completed.");
 
            System.out.println("ID: " + result.id);
            System.out.println("Name: " + result.name);
            System.out.println("Marks: " + result.marks);
 
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Output

Serialization completed.
Deserialization completed.
ID: 101
Name: Rahul
Marks: 85.5

9. Why Does the Class Need Serializable?

Suppose we create a class without implementing Serializable.

class Student {
 
    int id;
    String name;
}

Then:

output.writeObject(student);

will fail because the object is not serializable through Java's standard object serialization mechanism.

Typically, a NotSerializableException is thrown.

Therefore, the class should implement:

implements Serializable

10. Serializable Is a Marker Interface

The Serializable interface does not define methods that your class must implement.

For example:

public interface Serializable {
}

Conceptually, it acts as a signal to Java's serialization mechanism that instances of the class can participate in standard serialization.

11. serialVersionUID

serialVersionUID is a version identifier associated with a serializable class.

Example

class Student implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    int id;
    String name;
}

It helps Java determine whether the class used during deserialization is compatible with the class that was used during serialization.

12. Why Use serialVersionUID?

Suppose an object is serialized using one version of a class.

Later, the class is changed.

For example, originally:

class Student implements Serializable {
 
    int id;
    String name;
}

Later:

class Student implements Serializable {
 
    int id;
    String name;
    double marks;
}

Java can use serialVersionUID to determine whether the serialized data is compatible with the current class definition.

A common practice is:

private static final long serialVersionUID = 1L;

The value should be changed intentionally when a class change is meant to make previously serialized data incompatible.

13. Example with serialVersionUID

import java.io.Serializable;
 
class Student implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    int id;
    String name;
    double marks;
 
    Student(int id, String name, double marks) {
        this.id = id;
        this.name = name;
        this.marks = marks;
    }
}

This explicitly defines the serialization version.

14. What is transient?

The transient keyword is used to exclude a field from default serialization.

Suppose we have:

class Student implements Serializable {
 
    int id;
    String name;
    transient String password;
}

When the object is serialized, the password field is not included in the default serialized state.

15. Example of transient

import java.io.*;
 
class Student implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    int id;
    String name;
    transient String password;
 
    Student(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Student student =
                new Student(101, "Rahul", "abc123");
 
        try (ObjectOutputStream output =
                     new ObjectOutputStream(
                             new FileOutputStream("student.ser"))) {
 
            output.writeObject(student);
 
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        try (ObjectInputStream input =
                     new ObjectInputStream(
                             new FileInputStream("student.ser"))) {
 
            Student result =
                    (Student) input.readObject();
 
            System.out.println("ID: " + result.id);
            System.out.println("Name: " + result.name);
            System.out.println("Password: " + result.password);
 
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Output

ID: 101
Name: Rahul
Password: null

Because password was declared as:

transient String password;

its value is not restored by default serialization.

For a reference field, its default value after deserialization is null.

16. Default Values of Transient Fields

Transient fields are not restored from the serialized stream by default.

Their values after deserialization are their normal Java default values.

Examples:

TypeDefault value
int0
long0L
double0.0
booleanfalse
char'\u0000'
Object referencenull

17. Why Use transient?

A field may be marked transient when its value should not be included in the default serialized state.

Examples can include:

  • Temporary calculated values
  • Runtime-only state
  • Values that should be reconstructed
  • Data that should not be persisted through default serialization

However, transient should not be treated as a complete security mechanism for sensitive information. Application-specific security requirements need appropriate protection.

18. Static Fields and Serialization

Static fields belong to the class rather than an individual object.

They are not part of the object's normal instance state serialized by Java's default serialization mechanism.

Example

class Student implements Serializable {
 
    int id;
    String name;
 
    static String college = "ABC College";
}

The instance fields:

id
name

belong to the object.

The static field:

college

belongs to the class.

Therefore, changing a static field after serialization can affect what is observed through the class after deserialization.

19. Serialization of Multiple Objects

We can write multiple objects to the same ObjectOutputStream.

Example

import java.io.*;
 
class Student implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    int id;
    String name;
 
    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Student first =
                new Student(101, "Rahul");
 
        Student second =
                new Student(102, "Priya");
 
        try (ObjectOutputStream output =
                     new ObjectOutputStream(
                             new FileOutputStream("students.ser"))) {
 
            output.writeObject(first);
            output.writeObject(second);
 
            System.out.println("Objects serialized.");
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

20. Deserializing Multiple Objects

The objects should be read in the same sequence in which they were written.

import java.io.*;
class Student implements Serializable {
 
    int id;
    String name;
 
    static String college = "ABC College";
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        try (ObjectInputStream input =
                     new ObjectInputStream(
                             new FileInputStream("students.ser"))) {
 
            Student first =
                    (Student) input.readObject();
 
            Student second =
                    (Student) input.readObject();
 
            System.out.println(
                    first.id + " " + first.name);
 
            System.out.println(
                    second.id + " " + second.name);
 
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Output

101 Rahul
102 Priya

21. Serializing an ArrayList

Collections can also be serialized when their contents are serializable.

For example, ArrayList implements Serializable.

Example

import java.io.*;
import java.util.ArrayList;
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        ArrayList<String> names = new ArrayList<>();
 
        names.add("Rahul");
        names.add("Priya");
        names.add("Amit");
 
        try (ObjectOutputStream output =
                     new ObjectOutputStream(
                             new FileOutputStream("names.ser"))) {
 
            output.writeObject(names);
 
            System.out.println("List serialized.");
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

22. Deserializing an ArrayList

import java.io.*;
import java.util.ArrayList;
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        try (ObjectInputStream input =
                     new ObjectInputStream(
                             new FileInputStream("names.ser"))) {
 
            ArrayList<String> names =
                    (ArrayList<String>) input.readObject();
 
            System.out.println(names);
 
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Output

[Rahul, Priya, Amit]

23. Serialization of Object References

Consider:

class Address implements Serializable {
 
    String city;
 
    Address(String city) {
        this.city = city;
    }
}

And:

class Student implements Serializable {
 
    int id;
    String name;
    Address address;
 
    Student(int id, String name, Address address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }
}

If Student is serialized, the referenced Address object must also be serializable if it is part of the object's serializable state.

Example

import java.io.*;
 
class Address implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    String city;
 
    Address(String city) {
        this.city = city;
    }
}
 
class Student implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    int id;
    String name;
    Address address;
 
    Student(int id, String name, Address address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }
}

Both classes implement:

Serializable

so the object graph can be serialized using default serialization.

24. What Happens if a Referenced Object Is Not Serializable?

Suppose:

class Address {
 
    String city;
}

does not implement Serializable.

But:

class Student implements Serializable {
 
    Address address;
}

contains an Address instance.

When the Student object is serialized, Java attempts to serialize its non-transient referenced state as well.

If the referenced Address object is not serializable, serialization can fail with:

NotSerializableException

A common solution is to make the referenced class serializable when it should be part of the serialized state:

class Address implements Serializable {
}

Or, if that reference should not be serialized, consider whether it should be marked transient.

25. Custom Serialization

Java also allows a class to customize how its state is serialized and deserialized.

A class can define:

private void writeObject(ObjectOutputStream out)
        throws IOException

and:

private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException

These methods can be used to control serialization behavior.

26. Custom writeObject() Example

import java.io.*;
 
class Student implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    int id;
    String name;
 
    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
 
    private void writeObject(ObjectOutputStream out)
            throws IOException {
 
        out.defaultWriteObject();
 
        System.out.println("Custom serialization logic executed.");
    }
}

The call:

out.defaultWriteObject();

allows Java's default serialization mechanism to handle the normal serializable fields.

27. Custom readObject() Example

private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException {
 
    in.defaultReadObject();
 
    System.out.println("Custom deserialization logic executed.");
}

Together:

private void writeObject(ObjectOutputStream out)
        throws IOException {
 
    out.defaultWriteObject();
}
 
private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException {
 
    in.defaultReadObject();
}

These methods provide hooks for custom serialization behavior.

28. Serialization and Object Identity

Serialization preserves object references within the serialized object graph.

For example, if two fields point to the same object:

Address address = new Address("Bangalore");
 
Student first = new Student(address);
Student second = new Student(address);

and the containing object graph is serialized, Java's serialization mechanism tracks references so that shared references can be preserved when the graph is reconstructed.

This is one reason serialization is more than simply writing each field independently.

29. ObjectOutputStream vs ObjectInputStream

ClassPurpose
ObjectOutputStreamWrites objects
ObjectInputStreamReads objects

Example

ObjectOutputStream output =
        new ObjectOutputStream(
                new FileOutputStream("data.ser"));

For reading:

ObjectInputStream input =
        new ObjectInputStream(
                new FileInputStream("data.ser"));

30. Important Exceptions

Serialization and deserialization can involve several exceptions.

IOException

Used for input/output problems.

Example

catch (IOException e) {
    e.printStackTrace();
}

ClassNotFoundException

readObject() can throw this when the class information needed to reconstruct an object cannot be found.

Example

catch (ClassNotFoundException e) {
    e.printStackTrace();
}

NotSerializableException

This can occur when Java's standard serialization mechanism encounters an object that is not serializable.

31. Practical Example: Employee Object

import java.io.*;
 
class Employee implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    int id;
    String name;
    double salary;
 
    Employee(int id, String name, double salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Employee employee =
                new Employee(501, "Amit", 75000);
 
        // Serialization
        try (ObjectOutputStream output =
                     new ObjectOutputStream(
                             new FileOutputStream("employee.ser"))) {
 
            output.writeObject(employee);
 
            System.out.println("Employee serialized.");
 
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        // Deserialization
        try (ObjectInputStream input =
                     new ObjectInputStream(
                             new FileInputStream("employee.ser"))) {
 
            Employee result =
                    (Employee) input.readObject();
 
            System.out.println("Employee deserialized.");
 
            System.out.println("ID: " + result.id);
            System.out.println("Name: " + result.name);
            System.out.println("Salary: " + result.salary);
 
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Output

Employee serialized.
Employee deserialized.
ID: 501
Name: Amit
Salary: 75000.0

32. Serialization Process

The serialization process can be visualized as:

Employee Object
       |
       v
ObjectOutputStream
       |
       v
Byte Stream
       |
       v
employee.ser

The object state is converted into a serialized representation.

33. Deserialization Process

The reverse process is:

employee.ser
     |
     v
Byte Stream
     |
     v
ObjectInputStream
     |
     v
Employee Object

The object can then be used by the Java application.

34. Serialization vs Normal File Writing

Normal text writing:

Files.writeString(
    Path.of("student.txt"),
    "101,Rahul,85"
);

stores text.

Object serialization:

output.writeObject(student);

stores the object's serialized state in a Java serialization stream.

These approaches serve different purposes.

Text/JSON/XML-style formats are often useful when data needs to be human-readable or interoperable with other technologies.

Java serialization is specifically designed for Java object serialization and has its own compatibility and security considerations.

35. Serialization and Security

Deserializing untrusted Java serialization data can be dangerous.

For example:

input.readObject();

should not be treated as harmless if the input comes from an untrusted source.

Applications should avoid blindly deserializing untrusted data and should use safer data-exchange formats or appropriate filtering and validation where applicable.

For data exchange between different applications, formats such as JSON are often preferred because they provide clearer data contracts and broader interoperability.

36. Common Mistakes

Mistake 1: Not Implementing Serializable

Incorrect:

class Student {
}

when attempting:

output.writeObject(student);

Correct:

class Student implements Serializable {
}

when Java's standard object serialization is intended.

Mistake 2: Forgetting serialVersionUID

It is good practice to explicitly declare:

private static final long serialVersionUID = 1L;

for serializable classes whose serialized form may need compatibility management.

Mistake 3: Forgetting to Close Streams

Prefer try-with-resources:

try (ObjectOutputStream output =
         new ObjectOutputStream(
                 new FileOutputStream("data.ser"))) {
 
    output.writeObject(object);
}

Mistake 4: Assuming transient Means "Encrypted"

It does not.

For example:

transient String password;

does not encrypt the password.

It simply excludes that field from default Java serialization.

Mistake 5: Deserializing Untrusted Data

Avoid blindly doing:

input.readObject();

with data received from an untrusted source.

Deserialization should be performed only with appropriate trust and security controls.

37. Important Keywords and Classes

Keyword/ClassPurpose
SerializableMarks a class as serializable
ObjectOutputStreamSerializes objects
ObjectInputStreamDeserializes objects
transientExcludes a field from default serialization
serialVersionUIDIdentifies a serialization version
writeObject()Writes an object
readObject()Reads an object
writeObject() custom methodCustomizes serialization
readObject() custom methodCustomizes deserialization

38. Frequently Asked Questions

Can an abstract class implement Serializable?

Yes.

abstract class Animal implements Serializable {
}

A subclass can then participate in serialization depending on its fields and object graph.

Can an interface extend Serializable?

Yes.

For example:

interface MyInterface extends Serializable {
}

Can a final class be serialized?

Yes.

For example:

final class Student implements Serializable {
}

There is no restriction preventing a final class from implementing Serializable.

Can static variables be serialized?

Static fields are not part of the object's normal instance state serialized by default serialization.

Can transient variables be serialized?

They are not included in default serialization.

Can a constructor be serialized?

No.

Constructors are not object fields and are not serialized.

During ordinary deserialization of a serializable class, its constructor is not invoked in the same way as a normal object creation using new.

39. Simple Real-World Example

Imagine a Java application that maintains a user's preferences:

class UserPreferences implements Serializable {
 
    String language;
    String theme;
    int fontSize;
}

The application can serialize the object:

UserPreferences Object
        |
        v
Serialization
        |
        v
preferences.ser

Later, the application can deserialize it:

preferences.ser
        |
        v
Deserialization
        |
        v
UserPreferences Object

The application can then restore the user's stored preferences.

40. Complete Concept Summary

Serialization

Object → Byte Stream

Main class:

ObjectOutputStream

Main method:

writeObject()

Deserialization

Byte Stream → Object

Main class:

ObjectInputStream

Main method:

readObject()

Required Interface

Serializable

Exclude a field

transient

Version identifier

serialVersionUID

41. Key Points to Remember

  1. Serialization converts an object's state into a byte stream.
  2. Deserialization converts the byte stream back into an object.
  3. A class normally implements Serializable to participate in Java's standard serialization mechanism.
  4. Serializable is a marker interface.
  5. ObjectOutputStream is used for serialization.
  6. ObjectInputStream is used for deserialization.
  7. writeObject() writes an object.
  8. readObject() reads an object.
  9. transient excludes a field from default serialization.
  10. Static fields are not part of the object's normal serialized instance state.
  11. serialVersionUID helps manage compatibility between class versions.
  12. Referenced objects in the serialized state generally also need to be serializable.
  13. NotSerializableException can occur when a required object is not serializable.
  14. readObject() can throw ClassNotFoundException.
  15. Try-with-resources is useful for automatically closing serialization streams.
  16. Java serialization data is not the same as ordinary human-readable text.
  17. Java serialization should not be used to deserialize untrusted data without appropriate security controls.
  18. JSON or another explicit data format may be preferable when interoperability and human readability are important.

Conclusion

Java Serialization and Deserialization provide a mechanism for converting Java objects to a serialized byte representation and reconstructing objects from that representation.

The basic process is:

             SERIALIZATION
 
Java Object
     |
     v
ObjectOutputStream
     |
     v
Byte Stream
     |
     v
File / Storage
 
 
            DESERIALIZATION
 
File / Storage
     |
     v
Byte Stream
     |
     v
ObjectInputStream
     |
     v
Java Object

The most important concepts to understand are:

Serializable
ObjectOutputStream
ObjectInputStream
writeObject()
readObject()
transient
serialVersionUID

Once these concepts are understood, you can use Java's serialization mechanism to store and reconstruct object state while also understanding its compatibility and security considerations.

See you in next page....🙂

← Java File HandlingOverview →
← Java File HandlingOverview →