DEV Community

Sadiul Hakim
Sadiul Hakim

Posted on

Java Serializable Tutorial

1. What is Serializable?

Serializable is a marker interface in Java (java.io.Serializable).

  • A marker interface means it has no methods; it simply marks a class as being serializable.
  • Serialization = converting a Java object into a byte stream (so it can be saved to disk, transferred over a network, or stored in memory).
  • Deserialization = reconstructing the object back from the byte stream.

Example:

import java.io.*;

class Person implements Serializable {
    private String name;
    private int age;

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

public class SerializationExample {
    public static void main(String[] args) throws Exception {
        Person p = new Person("Alice", 25);

        // Serialize
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"));
        oos.writeObject(p);
        oos.close();

        // Deserialize
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"));
        Person deserialized = (Person) ois.readObject();
        ois.close();

        System.out.println("Deserialized: " + deserialized);
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Why do we need it?

We use serialization when we need to persist or transfer object states.

Common use cases:

  • Saving objects: Writing them to a file, caching, or database blob.
  • Sending objects: Across sockets (network communication, RMI, messaging).
  • Framework support: Many frameworks (like Java EE, Spring, Hibernate, JPA, distributed caches like Redis) rely on serialization to store/transfer entities.
  • Session management: Web servers serialize HTTP session objects when clustering/distributing across nodes.

3. When to use it and when NOT?

When to use:

  • Need to store objects temporarily (file, cache, DB).
  • Need to send objects across JVMs (RMI, messaging systems).
  • Required by a framework or API (like JPA, HttpSession, caching libraries).

When NOT to use:

  • When objects are not meant to persist (e.g., database connection, sockets, threads).
  • If object structure is very complex → serialization can be slow and heavy.
  • In microservices: Instead of Java native serialization (which is JVM-specific, fragile across versions), prefer JSON, Protocol Buffers, or Avro.

Performance Note:
Java’s native serialization is slow and insecure (possible Remote Code Execution if untrusted input). That’s why many modern systems avoid it in favor of JSON, Kryo, Protobuf, etc.


4. Key Concepts & Best Practices

serialVersionUID

  • Every Serializable class should define a unique version ID.
  • It helps JVM verify compatibility between serialized and deserialized classes.
  • If class definition changes and no serialVersionUID is defined, JVM will auto-generate one, which may cause InvalidClassException on deserialization.
private static final long serialVersionUID = 1L;
Enter fullscreen mode Exit fullscreen mode

Transient fields

  • Fields marked transient are not serialized.
  • Useful for sensitive or non-serializable fields.
class User implements Serializable {
    private String username;
    private transient String password; // won’t be serialized
}
Enter fullscreen mode Exit fullscreen mode

Customizing serialization

You can control the process by defining:

private void writeObject(ObjectOutputStream out) throws IOException {
    out.defaultWriteObject(); // default serialization
    // custom logic
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject(); // default deserialization
    // custom logic
}
Enter fullscreen mode Exit fullscreen mode

5. Why is it used on JPA Entities?

You’ll often see JPA entities implementing Serializable, like:

@Entity
public class Employee implements Serializable {
    @Id
    private Long id;
    private String name;
}
Enter fullscreen mode Exit fullscreen mode

Reasons:

  1. Hibernate/JPA requirement:
  • JPA spec recommends entities be serializable (not mandatory, but good practice).
  • Entities might be stored in second-level cache, which may require serialization.
  1. Distributed environments:
  • If you store entities in HTTP sessions, application servers (Tomcat, WildFly, etc.) may serialize them when clustering/distributing sessions.
  1. Safety for frameworks:
  • Some frameworks serialize objects when performing lazy loading or proxying.

Even if your app is single-node, marking entities as Serializable ensures compatibility when scaling.


6. When to Avoid Serializable on Entities

  • If you never store entities in sessions/cache and always use DTOs for data transfer → Serializable isn’t strictly necessary.
  • In modern REST APIs, entities are usually converted to JSON and sent, so you don’t always rely on Java serialization.

7. Alternatives to Java Serialization

Since Java native serialization is slow and insecure, many production systems prefer:

  • JSON (Jackson, Gson)
  • Kryo (fast binary serialization)
  • Google Protocol Buffers (Protobuf)
  • Apache Avro

Summary

  • Serializable is a marker interface to convert objects into byte streams.
  • Needed for object persistence, caching, and transfer.
  • Use serialVersionUID, transient, and possibly custom writeObject/readObject.
  • JPA entities often implement it for caching, clustering, and session management.
  • Don’t use it blindly → for microservices & APIs, prefer JSON or Protobuf.

Top comments (0)