0
0
JavaComparisonIntermediate · 4 min read

Serializable vs Externalizable in Java: Key Differences and Usage

In Java, Serializable is a marker interface that enables automatic object serialization, while Externalizable requires explicit implementation of serialization methods for full control. Externalizable is more flexible but needs manual coding, unlike Serializable which is simpler to use.
⚖️

Quick Comparison

This table summarizes the main differences between Serializable and Externalizable interfaces in Java.

FeatureSerializableExternalizable
Interface TypeMarker interface (no methods)Extends Serializable, requires methods
Control over SerializationAutomatic default serializationFull manual control via methods
Methods to ImplementNonewriteExternal(ObjectOutput) and readExternal(ObjectInput)
PerformanceSlower due to reflection and default processFaster if optimized manually
Use CaseSimple serialization needsCustom serialization logic required
Version CompatibilitySupports serialVersionUID for versioningAlso supports serialVersionUID, but manual handling needed
⚖️

Key Differences

Serializable is a marker interface, meaning it has no methods to implement. When a class implements it, Java automatically handles the serialization process using reflection. This makes it very easy to use but offers limited control over how the object's data is saved and restored.

On the other hand, Externalizable extends Serializable but requires the class to implement two methods: writeExternal(ObjectOutput out) and readExternal(ObjectInput in). These methods let the programmer define exactly how the object's state is written and read, giving full control over serialization. This can improve performance and allow custom handling of transient or sensitive data.

Because Externalizable requires manual coding, it is more complex but useful when default serialization is not efficient or secure. Also, Serializable uses reflection which can be slower, while Externalizable can be optimized for speed and size.

⚖️

Code Comparison

java
import java.io.*;

class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    String name;
    int age;

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

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

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

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

        // Deserialize
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
            Person p2 = (Person) ois.readObject();
            System.out.println(p2);
        }
    }
}
Output
Person{name='Alice', age=30}
↔️

Externalizable Equivalent

java
import java.io.*;

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

    // Mandatory public no-arg constructor
    public Person() {}

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

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeUTF(name);
        out.writeInt(age);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = in.readUTF();
        age = in.readInt();
    }

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

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

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

        // Deserialize
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
            Person p2 = (Person) ois.readObject();
            System.out.println(p2);
        }
    }
}
Output
Person{name='Alice', age=30}
🎯

When to Use Which

Choose Serializable when you want quick and easy serialization without writing extra code. It is suitable for most cases where default behavior is enough and you don't need to customize how data is saved.

Choose Externalizable when you need full control over the serialization process, such as optimizing performance, handling sensitive data carefully, or customizing the format. It requires more work but offers flexibility and efficiency.

Key Takeaways

Serializable is simple and automatic but less flexible.
Externalizable requires manual coding but gives full control.
Use Serializable for standard cases and Externalizable for custom serialization needs.
Externalizable can improve performance by avoiding default reflection.
Both support versioning with serialVersionUID.