JDK-4862448 : Unable to serialize anonymous classes.
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.io:serialization
  • Affected Version: 1.4.2
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2003-05-12
  • Updated: 2003-05-15
  • Resolved: 2003-05-15

Name: rmT116609			Date: 05/12/2003

Java does not allow anonymous classes to be serialized.

This is due to the fact that the constructor generated by the compiler for an anonymous class is done so automatically, and a no-argument constructor is not constructed; furthermore, the compiler prevents the developer from defining their own no-argument contructor for the anonymous class.

Object serialization requires that a no-argument constructor be defined.

There are many cases where it is desireable to have fields assigned objects using anonymous classes.

Correspondingly, it is oven desireable to serialize information (e.g., for network transport or for persistence).

Preventing the developer from serializing all anyonmous classes is a severe restriction.

The simplest solution is to automatically generate a no-argument constructor for all anonymous classes.
The current behavior prohibits the serialization of all anyonmous classes.
(Review ID: 185561) 

WORK AROUND See evaluation.

EVALUATION Object serialization only requires that a class defines a no-argument constructor if it is externalizable. If the class is serializable (but not externalizable), then the class itself does not need to define a no-argument constructor--its closest non-serializable superclass, however, must define a subclass-accessible no-argument constructor. For example, the following code successfully serializes and deserializes an anonymous class instance; this is possible because the anonymous class subclasses java.lang.Object, which defines a public no-arg constructor: import java.io.*; public class Foo { public static void main(String[] args) throws Exception { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream oout = new ObjectOutputStream(bout); oout.writeObject(new Serializable() { public String toString() { return "anonymous class instance"; } }); oout.close(); ObjectInputStream oin = new ObjectInputStream( new ByteArrayInputStream(bout.toByteArray())); System.out.println("deserialized: " + oin.readObject()); } } Serialization of anonymous class instances, however, is discouraged due to several known complications. These are spelled out in section 1.10 of the serialization specification: Note - 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 JavaTM 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. Since inner classes cannot declare static members other than compile-time constant fields, they cannot use the serialPersistentFields mechanism to designate serializable fields. Finally, 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. None of the issues listed above, however, apply to static member classes. Foremost among these issues is the fact that anonymous classes do not have well-defined names--it's up to the compiler to choose a name for the class. This means that if you take an application that serializes an anonymous class, and happen to compile the writing and reading ends of it with different versions/implementations of javac, then serialization of the class may very well fail, since there's no agreed name for the class (i.e., if the sender uses the class name Foo$1 and the receiver uses Foo$2, serialization has no way of knowing that Foo$1 should map to Foo$2). An easy workaround for this issue is to use a named class instead of an anonymous class. In light of the issues enumerated above, it's also recommended that this named class be either a non-nested class, or, if it must be nested, a static member class. ###@###.### 2003-05-15