不可序列化匿名类上的异常

我有一个用于过滤项目的界面:

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);
}

和包含 类型成员的类。KeyValFilter

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

当我尝试用一个匿名类实现来启动时:KeyValFilterCollectorKeyValFilter

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:");
        }
});

我得到一个例外:.Exception in thread "main" java.io.NotSerializableException

如何使我编写的匿名类可序列化?


答案 1

Joshua Bloch在他的书《Effective Java, 2nd Edition, Item 74》中写道:

内部类不应实现可序列化。它们使用编译器生成的综合字段来存储对封闭实例的引用,并存储封闭作用域中的局部变量值。这些字段与类定义的对应方式未指定,匿名类和本地类的名称也是如此。因此,内部类的默认序列化形式是错误定义的。但是,静态成员类可以实现 。Serializable


答案 2

通常,序列化匿名类时看到的问题在于封闭类不可序列化(并且作者没有意识到序列化匿名类涉及序列化其封闭类)。

匿名类是非静态内部类。这意味着它有一个隐藏字段,该字段引用封闭类的实例。当您使用 创建它而不显式限定它时(例如 ),则隐式用作封闭类的实例(就像您所做的那样)。因此,当您序列化匿名类时,这需要序列化其所有字段,其中一个是封闭类的实例,然后必须可序列化。new KeyValFilter(){ ... }something.new KeyValFilter(){ ... }thisthis.new KeyValFilter(){ ... }

如果不需要使用封闭类的任何字段或方法,则应改用静态内部类。(但是,它不能是匿名的或在方法中定义的。