Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NotSerializableException on anonymous class

I have an interface for filtering items:

public interface KeyValFilter extends Serializable {
    public static final long serialVersionUID = 7069537470113689475L;
    public boolean acceptKey(String iKey, Iterable<String> iValues);
    public boolean acceptValue(String iKey, String value);
}

and a class containing a member of type KeyValFilter.

public class KeyValFilterCollector extends KeyValCollectorSkeleton {
    private static final long serialVersionUID = -3364382369044221888L;
    KeyValFilter filter;
    public KeyValFilterCollector(KeyValFilter filter) {
        this.filter=filter;
    }
}

When I try to initiate the KeyValFilterCollector with an anonymous class implementing KeyValFilter:

new KeyValFilterCollector(new KeyValFilter() {
        private static final long serialVersionUID = 7069537470113689475L;
        public boolean acceptKey(String iKey, Iterable<String> iValues) {
            for (String value : iValues) {
                if (value.startsWith("1:"))
                        return true;
            }
            return false;
        }
        public boolean acceptValue(String iKey, String value) {
            return value.startsWith("0:");
        }
});

I get an exception: Exception in thread "main" java.io.NotSerializableException.

How do I make the anonymous class I wrote Serializable?

like image 348
Shaharg Avatar asked Jul 23 '13 08:07

Shaharg


People also ask

Can an anonymous class have a constructor?

Since anonymous inner class has no name, an anonymous inner class cannot have an explicit constructor in Java.

Can an anonymous class implement an interface?

A normal class can implement any number of interfaces but the anonymous inner class can implement only one interface at a time. A regular class can extend a class and implement any number of interfaces simultaneously. But anonymous Inner class can extend a class or can implement an interface but not both at a time.

Can anonymous class have multiple methods?

You can't. The only way to be able to call multiple methods is to assign the anonymous class instance to some variable.

Can Anonymous classes be private?

3.12. An anonymous class cannot define any static fields, methods, or classes, except for staticfinal constants. Interfaces cannot be defined anonymously, since there is no way to implement an interface without a name. Also, like local classes, anonymous classes cannot be public, private, protected, or static.


2 Answers

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.

like image 158
Martin Höller Avatar answered Oct 05 '22 19:10

Martin Höller


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.)

like image 40
newacct Avatar answered Oct 05 '22 17:10

newacct