Serialization (Serializable, transient)
Serialization is the process of converting a Java object into a stream of bytes that can be stored or transmitted, and later turned back into an equal object — a powerful but security-sensitive part of the platform.
Learn Serialization (Serializable, transient) in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and…
Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Before You Start
You should know classes and objects , interfaces (Serializable is one), and have seen exceptions — these stream operations throw several checked ones.
What You'll Learn
The Big Idea — Flat-Packing Furniture
💡 Analogy: Serialization is like flat-packing a piece of furniture to ship it. The assembled chair (your object) is broken down into a flat box of parts (bytes) that can be stored or posted, then rebuilt into an identical chair at the other end (deserialization). transient fields are the parts you deliberately leave out of the box — the cushions you'll buy fresh on arrival. And serialVersionUID is the model number printed on the box: if the assembly instructions at the destination are for a different model number, you refuse to build it rather than produce a broken chair.
All examples below flat-pack into an in-memory ByteArrayOutputStream instead of a file, so they run anywhere with no disk access — and print the real round-tripped result.
1️⃣ A Basic Round-Trip
Implement Serializable , declare a serialVersionUID , then write with ObjectOutputStream.writeObject and read back with ObjectInputStream.readObject (casting the result). We serialize into a byte array so the example needs no file.
2️⃣ transient — Fields That Don't Travel
Mark a field transient to keep it out of the byte stream — for secrets like a password , recomputable caches, or non-serializable references. After deserialization those fields hold their default value ( null for objects, 0 for numbers).
3️⃣ serialVersionUID & Compatibility
The serialVersionUID is a version stamp. On read, Java compares the stream's UID with the current class's; a mismatch throws InvalidClassException . Always declare it explicitly — otherwise the compiler auto-generates one that changes on almost any edit, silently breaking old data.
⚠️ The Big Security Warning
Java's native deserialization is one of the platform's most exploited features. Deserializing bytes from an untrusted source can instantiate arbitrary classes and execute code during reconstruction — so-called gadget chains that have produced many real-world remote-code-execution CVEs.
- Never deserialize data you don't fully trust.
- For data crossing system boundaries, prefer JSON (Jackson/Gson) — language-neutral, human-readable, and far safer.
- If you must use object streams on external input, apply an ObjectInputFilter allow-list.
🧠 Quick Recall
Answer: 0 — its type default. Transient fields aren't written, so on restore objects are null and numbers are 0 / 0.0 .
Answer: NotSerializableException at write time, naming the offending class. Make that type Serializable or mark the field transient .
Answer: not with native Java serialization — untrusted streams can trigger code execution. Use JSON for external data, or a strict ObjectInputFilter if you truly must.
🎯 YOUR TURN — Skip a cache field
Add a transient cache field to Book so the title persists but the cache comes back null .
🧩 MINI-CHALLENGE — Generic round-trip helper
Write using in-memory streams, and prove the restored Cart has equal contents but is a different object.
Common Errors
- ❌ Forgetting to implement Serializable. NotSerializableException . Fix: implement it on the class and every non-transient referenced type.
- ❌ No declared serialVersionUID. Edits silently break old data. Fix: declare private static final long serialVersionUID .
- ❌ Serializing secrets. Passwords end up in the blob. Fix: mark them transient — or don't serialize the object.
- ❌ Expecting transient fields to survive. They reset to defaults. Fix: recompute them after restore, or don't make them transient.
- ❌ Deserializing untrusted data. Remote code execution risk. Fix: use JSON, or an ObjectInputFilter allow-list.
- ❌ Ignoring the checked exceptions. readObject throws IOException and ClassNotFoundException . Fix: declare or catch them.
Pro Tips
- 💡 Prefer JSON for data exchange. It's portable across languages, debuggable by eye, and dodges the deserialization-attack surface entirely.
- 💡 Always declare serialVersionUID on any Serializable class to control compatibility deliberately.
- 💡 Use ByteArrayOutputStream to test serialization without touching the filesystem.
- 💡 Records are serializable too, but their serialization is based on components and is more robust against the classic attacks.
📋 Quick Reference
Concept
Syntax
Note
mark serializable
implements Serializable
Marker interface
version stamp
static final long serialVersionUID
Always declare it
skip a field
transient
Not written
write object
out.writeObject(obj)
ObjectOutputStream
read object
(T) in.readObject()
Cast the result
in-memory out
ByteArrayOutputStream
No file needed
in-memory in
ByteArrayInputStream
Wrap the bytes
not serializable
NotSerializableException
Field type fails
version mismatch
InvalidClassException
UID differs
security filter
ObjectInputFilter
Allow-list classes
safer alternative
JSON (Jackson/Gson)
For external data
📚 Resources / Keep Learning
- 📘 Serializable — Java 21 API documentation (docs.oracle.com)
- 📘 ObjectInputStream — Java 21 API (docs.oracle.com)
- 📘 Serialization Filtering (security) — Java 21 Core Guide (docs.oracle.com)
❓ Frequently Asked Questions
🎉 Lesson Complete!
You can now make a class Serializable , round-trip it through ObjectOutputStream / ObjectInputStream using in-memory byte arrays, control what travels with transient , manage compatibility with serialVersionUID , and — crucially — respect the deserialization security risks by preferring JSON for untrusted data.
Next up: Checkpoint: Practical Java — a build challenge that combines collectors, builders, immutability, equals/hashCode and more.
Practice quiz
What is serialization?
- Sorting objects
- Encrypting data
- Converting an object into a byte stream
- Compiling code
Answer: Converting an object into a byte stream. Serialization turns an object's state into a sequence of bytes that can be stored or transmitted, and later reconstructed (deserialized).
Which interface marks a class as serializable?
- Serializable
- Comparable
- Cloneable
- Runnable
Answer: Serializable. A class must implement java.io.Serializable (a marker interface with no methods) to be serialized by ObjectOutputStream.
Which stream writes an object to bytes?
- ObjectInputStream
- PrintStream
- DataOutputStream
- ObjectOutputStream
Answer: ObjectOutputStream. ObjectOutputStream.writeObject(obj) serializes; ObjectInputStream.readObject() deserializes.
What does the transient keyword do to a field?
- Makes it final
- Excludes it from serialization
- Makes it static
- Encrypts it
Answer: Excludes it from serialization. A transient field is skipped during serialization and comes back as its default value (null or 0) after deserialization.
What is serialVersionUID for?
- Version compatibility between serialized and current class
- Object identity
- Thread safety
- Hashing
Answer: Version compatibility between serialized and current class. It identifies a class version; if a stream's UID doesn't match the loaded class, deserialization throws InvalidClassException.
What happens to a transient field after deserialization?
- Keeps its old value
- Throws an exception
- Becomes its default (null/0)
- Becomes final
Answer: Becomes its default (null/0). Transient fields are not written, so on restore they hold the type's default — null for objects, 0 for numbers.
Why is Java deserialization a security risk?
- It's slow
- Untrusted byte streams can be crafted to execute malicious code (gadget chains)
- It uses too much memory
- It's deprecated entirely
Answer: Untrusted byte streams can be crafted to execute malicious code (gadget chains). Deserializing untrusted data can trigger 'gadget chains' leading to remote code execution — never deserialize data you don't trust.
A safer modern alternative to Java serialization for data exchange is...
- Object streams
- transient
- Reflection
- JSON (e.g. Jackson/Gson)
Answer: JSON (e.g. Jackson/Gson). Text formats like JSON are language-neutral, human-readable, and far safer for exchanging data across systems.
If you serialize a class that references another object, that object must also...
- be transient
- implement Serializable (or be transient)
- be final
- be static
Answer: implement Serializable (or be transient). All non-transient referenced objects must themselves be Serializable, or you get NotSerializableException.
What does ObjectInputStream.readObject() return?
- A String
- void
- An Object you must cast
- An int
Answer: An Object you must cast. readObject() returns Object, so you cast it to the expected type — and it can throw ClassNotFoundException.
Continue this course
- Previous: Dependency Injection
- Next: Checkpoint: Practical Java