FindBugs没有抱怨枚举中的非序列化字段

时间:2016-08-29 10:07:55

标签: java serialization enums findbugs

如果我有课程:

class NonSerializable {
}

class CanSerialize implements Serializable {
    private static final long serialVersionUID = 0L;
    public NonSerializable nonSerializable;
}

FindBugs引发违规行为

<BugInstance rank="14" category="BAD_PRACTICE" priority="1" abbrev="Se" type="SE_BAD_FIELD">

这看起来是正确的。

但是,当我将代码更改为:

class NonSerializable {
}

enum CanSerialize {
    INSTANCE;
    public NonSerializable nonSerializable;
}

FindBugs不再抱怨了。它是FindBugs中的错误还是在枚举中具有非瞬态,不可序列化的字段是安全的?

1 个答案:

答案 0 :(得分:2)

一方面,您的问题的答案是在枚举中安装非瞬态非序列化字段是安全的。另一方面,它们在枚举时不会被序列化。因此,即使它们没有被声明为瞬态,它们也会像瞬态场一样工作。

来自Java对象序列化规范:

  

1.12枚举常量的序列化   枚举常量的序列化与普通的可序列化或可外部化的对象不同。该   枚举常量的序列化形式仅由其名称组成;领域   常量的值不在表格中。序列化   枚举常量,ObjectOutputStream写入返回的值   枚举常量的名称方法。要反序列化枚举常量,   ObjectInputStream从流中读取常量名称;该   然后通过调用,获得反序列化的常量   java.lang.Enum.valueOf方法,传递常量的枚举类型   将收到的常量名称作为参数。像其他可序列化的   或可外部化的对象,枚举常量可以作为目标   随后出现在序列化流中的后向引用。

http://docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/serial-arch.html#enum

因此,NonSerializable是否可序列化并不会产生任何影响。因此,FindBugs在枚举中不标记这一点是正确的。

如果我猜测,枚举中的字段通常是最终的并且在类加载器加载枚举时初始化,所以也许他们认为序列化它们没有意义,它们可以再次初始化枚举器加载枚举的时间。这不是我所知道的。

相关问题