Serializable vs Externalizable in Java — Which to Use for Performance
Fast recall
Quick revision
Core answer
Serializable and demands you implement writeExternal(ObjectOutput) and readExternal(ObjectInput) by hand — you control exactly which bytes are written. Faster (no reflection), smaller (no auto-written metadata), and safer. In 2026, avoid both Java built-in serialization for anything externally exposed or performance-critical. Use Protocol Buffers, Avro, FlatBuffers, or JSON (Jackson) instead. Use Externalizable or custom writeObject/readObject only for internal caching or legacy compatibility where native serialization is mandated.Whether the candidate knows the two interfaces, the mechanism (reflection vs manual), the performance characteristics, and — critically — the security risks of Java native serialization
Not knowing that `Externalizable` objects require a public no-arg constructor (reconstructed with `newInstance()`, not via reflection). Recommending Java serialization over the wire — that's a security anti-pattern
Mention the serialization CVEs (Apache Commons Collections gadget chain, Struts2 RCE), JEP 290 serialization filters, and JEP 415 context-specific filters. Note that `Externalizable` bypasses `serialVersionUID` drift, but still doesn't solve the deserialization gadget problem
Interview-ready guide
Interview answer
Serializable and Externalizable both turn objects into bytes, but they take opposite approaches.
`Serializable` — the convenience option
- Marker interface with no methods
- JVM uses reflection to walk the object graph and write every non-transient, non-static field
- Class metadata (field names, types,
serialVersionUID) is embedded in every stream - On read, the object is allocated without calling any constructor — your invariants are skipped
- Customize with private
writeObject()/readObject()methods orwriteReplace/readResolve
`Externalizable` — the control option
- Extends
Serializable, addswriteExternal(ObjectOutput)andreadExternal(ObjectInput)that you implement - You write every byte manually; JVM contributes almost nothing
- Requires a public no-arg constructor, which IS called at deserialization time
- Then
readExternalpopulates state - No class-field descriptor in the stream
Performance difference
Externalizableis typically 2–4× faster and produces 30–60% smaller streams- Wins come from avoiding reflection and auto-written field descriptors
- The cost: you maintain the serialization code and versioning by hand
The security elephant in the room
- Both share Java's native deserialization attack surface
- Apache Commons Collections (CVE-2015-4852) — remote code execution via gadget chains
- Apache Struts2 (CVE-2017-5638) — the Equifax breach, hundreds of millions of records
- JEP 290 (Java 9) added
ObjectInputFilterallow/denylists - JEP 415 (Java 17) added context-specific filter factories
- Rule: never deserialize Java native format from untrusted sources
What I actually use in 2026
- Internal JVM-to-JVM (cache, session replication):
Externalizableif performance matters, elseSerializable - Cross-process, cross-language, or anything crossing trust boundaries: Protocol Buffers, Avro, FlatBuffers, or JSON (Jackson)
- Kafka event streams: Avro with Confluent Schema Registry
- REST APIs: Jackson JSON with Java records for DTOs
- Ultra-performance binary: FlatBuffers or Cap'n Proto — zero-copy reads beat Java serialization by 10–100×
Recommendation: Reach for Externalizable over Serializable only when you're locked into Java native serialization (legacy RMI, session replication, specific framework mandate) and profiling shows the overhead matters. For any new design in 2026, skip both and pick Jackson (JSON) for flexible APIs, Protocol Buffers for typed contracts, or Avro for streaming pipelines. If you do use native serialization, always configure `ObjectInputFilter` allowlists — the security cost of omitting this has been measured in billions of dollars across the industry.
`Serializable` vs `Externalizable` in Java — Which to Use for Performance
Direct Answer
Both are contracts for converting objects to bytes. Serializable is a marker interface — the JVM uses reflection to read/write every non-transient field automatically. Simple, but slow (reflection, full class metadata), bulky (class descriptor in every stream), and insecure (has been the source of many CVEs). Externalizable extends Serializable and demands you implement writeExternal(ObjectOutput) and readExternal(ObjectInput) by hand — you control exactly which bytes are written. Faster (no reflection), smaller (no auto-written metadata), and safer. In 2026, avoid both Java built-in serialization for anything externally exposed or performance-critical. Use Protocol Buffers, Avro, FlatBuffers, or JSON (Jackson) instead. Use Externalizable or custom writeObject/readObject only for internal caching or legacy compatibility where native serialization is mandated.
Common Mistakes & Pitfalls
Not knowing that Externalizable objects require a public no-arg constructor (reconstructed with newInstance(), not via reflection). Recommending Java serialization over the wire — that's a security anti-pattern
Check your understanding
Answer these without looking back at the article.
- Why does `Serializable` skip constructors but `Externalizable` doesn't?
- How does `serialVersionUID` work and when does it cause `InvalidClassException`?
- What's the role of `writeReplace()` and `readResolve()` in maintaining singleton semantics?
- How does `ObjectInputFilter` (JEP 290) prevent deserialization gadget attacks?
- Why are Protocol Buffers safer than Java native serialization?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.