"An inner class is a nested class that is not explicitly or implicitly declared static" [JLS 2015]. Serialization of inner classes (including local and anonymous classes) is error prone. According to the Serialization Specification [Sun 2006]:
- Serializing an inner class declared in a non-static context that contains implicit non-transient references to enclosing class instances results in serialization of its associated outer class instance.
- Synthetic fields generated by Java compilers to implement inner classes are implementation dependent and may vary between compilers; differences in such fields can disrupt compatibility as well as result in conflicting default
serialVersionUIDvalues. The names assigned to local and anonymous inner classes are also implementation dependent and may differ between compilers.
- Because inner classes cannot declare static members other than compile-time constant fields, they cannot use the
serialPersistentFieldsmechanism to designate serializable fields.
- Because inner classes associated with outer instances do not have zero-argument constructors (constructors of such inner classes implicitly accept the enclosing instance as a prepended parameter), they cannot implement
Externalizable. TheExternalizableinterface requires the implementing object to manually save and restore its state using thewriteExternal()andreadExternal()methods.
Consequently, programs must not serialize inner classes.
Because none of these issues apply to static member classes, serialization of static member classes is permitted.
Noncompliant Code Example
In this noncompliant code example, the fields contained within the outer class are serialized when the inner class is serialized:
public class OuterSer implements Serializable {
private int rank;
class InnerSer implements Serializable {
protected String name;
// ...
}
}
Compliant Solution
The InnerSer class of this compliant solution deliberately fails to implement the Serializable interface:
public class OuterSer implements Serializable {
private int rank;
class InnerSer {
protected String name;
// ...
}
}
Compliant Solution
If an inner and outer class must both be Serializable, the inner class can be declared static to prevent a serialized inner class from also serializing its outer class.
public class OuterSer implements Serializable {
private int rank;
static class InnerSer implements Serializable {
protected String name;
// ...
}
}
Risk Assessment
Serialization of inner classes can introduce platform dependencies and can cause serialization of instances of the outer class.
Rule | Severity | Likelihood | Detectable | Repairable | Priority | Level |
|---|---|---|---|---|---|---|
SER05-J | Medium | Likely | Yes | No | P12 | L1 |
Automated Detection
Detection of inner classes that implement serialization is straightforward.
| Tool | Version | Checker | Description |
|---|---|---|---|
| Klocwork | 2025.2 | JAVA.SERIALIZE.INNER | |
| SonarQube | 9.9 | S2066 S2059 | "Serializable" inner classes of non-serializable classes should be "static" "Serializable" inner classes of "Serializable" classes should be static |
Related Guidelines
Bibliography
[API 2014] | |
Item 74, "Implement Serialization Judiciously" | |
[JLS 2015] | |
[Sun 2006] | Serialization Specification, Section 1.10, "The Serializable Interface" |



14 Comments
David Svoboda
May 15, 2011The severity is medium because of the potential for sensitive info disclosure, if an inner class serializes a sensitive outer class.
The likelihood is 'likely' becaus an inner class would always serialize an outer class.
Changed the remediation cost is 'medium' because a serializable inner class is easy to detect by automated tools. But unless the inner class says 'implements Serializable', fixing the problem requires manual intervention.
Yozo TODA
Sept 07, 2011Bibliography?
[JLS 2005]
Section 8.1.3, Inner Classes and Enclosing Instances
[Sun 2006]
Java Object Serialization Specification, Section 1.10 The Serializable Interface
David Svoboda
Sept 07, 2011Yow! The bibliography got munched back in May! Restored it.
Yozo TODA
Sept 07, 2011how about the following refinement on the bibliography?
[API 2006]
Interface Externalizable
Interface Serializable
[Bloch 2008]
Item 74: "Implement
Serializationjudiciously"[JLS 2005]
Section 8.1.3, Inner Classes and Enclosing Instances
[Sun 2006]
"Serialization specification", Section 1.10 The Serializable Interface
David Svoboda
Sept 07, 2011Done.
Yozo TODA
Sept 08, 2011Why "section 1.10" is not added?
I believe the information (section 1.10) is useful for readers who want to check the original information.
For example, SER11-J has an entry
[Sun 2006]
Serialization Specification, A.7, Preventing Overwriting of Externalizable Objects
(I want to confirm if there is any policy on this...)
David Svoboda
Sept 08, 2011No policy, just didn't notice it (I was in a hurry). Fixed.
Yozo TODA
Nov 16, 2011I changed the paragraph at the last CS.
anyone please check if I understand things correctly?
OLD:
NEW:
more verbose writing with my understanding is:
David Svoboda
Nov 16, 2011I think both your OLD and NEW texts are accurate and correct.
Your 'more verbose writing' seems to indicate that serializing an outer class will also serialize an inner member class (unless it is static). That is not the danger...the danger is that serializing the inner class causes the outer class to also be serialized (unless the inner class is static).
Yozo TODA
Nov 16, 2011aha, my wording was incorrect.
looking back at code examples...
with this scenario, how about the revised paragraph at the 2nd CS:
OLD:
NEW:
David Svoboda
Nov 17, 2011Well, you can't say 'must', because declaring the inner class static is not the only solution, and is sometimes not possible. This is one solution, and not the only possibility. Sorry, I prefer the OLD wording.
Yozo TODA
Nov 17, 2011I still think the "OLD wording" above is bad because
Serializable." yes, so what?so, my (another) proposal is here
David Svoboda
Nov 18, 2011Good points. I rewrote the paragraph.
A Bishop
Jul 10, 2014Automated Detection:
Donar:
findbugs:SE_BAD_FIELD_INNER_CLASS
and
findbugs:SE_INNER_CLASS