Files
codeql/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.qhelp
Marcono1234 e21cbe82a9 Update Java documentation links to Java 11
Where possible update Java documentation links to Java 11.
Additionally update some other links to use HTTPS.
2021-02-26 00:43:51 +01:00

66 lines
3.0 KiB
XML

<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Non-static nested classes that implement <code>Serializable</code> must be defined in an enclosing class
that is also serializable. Non-static nested classes retain an implicit reference to
an instance of their enclosing class. If the enclosing class is not serializable, the Java
serialization mechanism fails with a <code>java.io.NotSerializableException</code>.
</p>
</overview>
<recommendation>
<p>
To avoid causing a <code>NotSerializableException</code>, do one of the following:
</p>
<ul>
<li>
<strong>Declare the nested class as <code>static</code> : </strong> If the nested class does not use any of the non-static
fields or methods of the enclosing class, it is best to declare it <code>static</code>. This removes the implicit reference to an instance of the enclosing
class, and has the additional effect of breaking an unnecessary dependency between the two classes. A similar solution is to
turn the nested class into a separate top-level class.
</li>
<li>
<strong>Make the enclosing class implement <code>Serializable</code> : </strong> However, this is not recommended because the implementation of inner classes may be compiler-specific, and
serializing an inner class can result in non-portability across compilers. The Java Serialization Specification states:
<blockquote><p>
Serialization of inner classes (i.e., nested classes that are not static member classes), including local and anonymous classes,
is strongly discouraged for several reasons. Because inner classes declared in non-static contexts contain implicit non-transient
references to enclosing class instances, serializing such an inner class instance will result in serialization of its associated
outer class instance as well. Synthetic fields generated by javac (or other Java(TM) 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 serialVersionUID values. The names assigned to local and anonymous inner classes are also implementation
dependent and may differ between compilers.
</p>
</blockquote>
</li>
</ul>
</recommendation>
<example>
<p>In the following example, the class <code>WrongSession</code> cannot be serialized without
causing a <code>NotSerializableException</code>, because it is enclosed by a non-serializable class.
However, the class <code>Session</code> can be serialized because it is declared as
<code>static</code>.</p>
<sample src="NonSerializableInnerClass.java" />
</example>
<references>
<li>
Java Object Serialization Specification:
<a href="https://docs.oracle.com/en/java/javase/11/docs/specs/serialization/serial-arch.html#the-serializable-interface">1.10 The Serializable Interface</a>,
<a href="https://docs.oracle.com/en/java/javase/11/docs/specs/serialization/output.html#the-objectoutputstream-class">2.1 The ObjectOutputStream Class</a>.
</li>
</references>
</qhelp>