匿名类上的notserializableexception

ssgvzors  于 2021-06-03  发布在  Hadoop
关注(0)|答案(3)|浏览(374)

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

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

当我尝试启动 KeyValFilterCollector 匿名类实现 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:");
        }
});

我有个例外: Exception in thread "main" java.io.NotSerializableException .
如何使我编写的匿名类可序列化?

ttcibm8c

ttcibm8c1#

您可以声明匿名类可序列化,但只有在该类的所有字段都可序列化的情况下,该类才是真正可序列化的。
参见示例:

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

如果你评论这句话

private Object ns = new Object(){};

否则,代码将成功完成 NotSerializableException 被抛出。

fruv7luv

fruv7luv2#

joshua bloch在其著作《有效的java》,第2版,第74项中写道:
内部类不应实现 Serializable . 它们使用编译器生成的合成字段来存储对封闭示例的引用,并存储封闭作用域中的局部变量值。这些字段如何与类定义相对应,以及匿名类和本地类的名称都未指定。因此,内部类的默认序列化形式没有定义。但是,静态成员类可以实现 Serializable .

dwthyt8l

dwthyt8l3#

通常,序列化匿名类时出现的问题是封闭类不可序列化(作者没有意识到序列化匿名类涉及序列化其封闭类)。
匿名类是一个非静态的内部类。这意味着它有一个引用封闭类示例的隐藏字段。当你用 new KeyValFilter(){ ... } ,没有明确限定它(例如。 something.new KeyValFilter(){ ... } ),那么 this 隐式地用作封闭类的示例(就像 this.new KeyValFilter(){ ... } ). 因此,在序列化匿名类时,需要序列化其所有字段,其中一个字段是封闭类的示例,该示例必须是可序列化的。
如果不需要使用封闭类的任何字段或方法,则应改用静态内部类(但是,它不能是匿名的,也不能在方法中定义。)

相关问题