NotSerializableException on anonymous class NotSerializableException on anonymous class hadoop hadoop

NotSerializableException on anonymous class


Joshua Bloch writes in his book Effective Java, 2nd Edition, Item 74:

Inner classes should not implement Serializable. They use compiler-generated synthetic fields to store references to enclosing instances and to store values of local variables from enclosing scopes. How these fields correspond to the class definition is unspecified, as are the names of anonymous and local classes. Therefore, the default serialized form of an inner class is illdefined. A static member class can, however, implement Serializable.


Usually, the problem seen when serializing anonymous class is that the enclosing class is not serializable (and the author failed to realize that serializing an anonymous class involves serializing its enclosing class).

An anonymous class is a non-static inner class. That means it has a hidden field which references an instance of the enclosing class. When you create it with new KeyValFilter(){ ... }, without explicit qualifying it (e.g. something.new KeyValFilter(){ ... }), then this is implicitly used as the instance of the enclosing class (as if you did this.new KeyValFilter(){ ... }). So when you serialize the anonymous class, that requires serializing all its fields, one of which is the instance of the enclosing class, which then must be serializable.

If you don't need to use any fields or methods of the enclosing class, you should use a static inner class instead. (It can't be anonymous or defined inside a method however.)


You can declare anonymous class serializable, but the class is only then really serializable, if all its fields are serializable.

See the example:

public static void main(String[] args) throws Exception {    Object myObj = new Serializable() {        private static final long serialVersionUID = 1L;        private String str = "something";        private Object ns = new Object(){};    };    ByteArrayOutputStream baos = new ByteArrayOutputStream();    ObjectOutputStream oos = new ObjectOutputStream(baos);    oos.writeObject(myObj);    oos.close();    System.out.println("Success!");}

If you comment the line

private Object ns = new Object(){};

The code finished with success, otherwise NotSerializableException is thrown.