java - FindBugs 不会提示枚举中的不可序列化字段

标签 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 中的错误还是在枚举中包含非 transient 、不可序列化字段是安全的?

最佳答案

一方面,您的问题的答案是在枚举中包含非 transient 不可序列化字段是安全的。另一方面,当枚举进行序列化时,它们不会被序列化。因此,即使它们没有被声明为 transient ,它们的工作方式仍然类似于 transient 字段。

来自 Java 对象序列化规范:

1.12 Serialization of Enum Constants Enum constants are serialized differently than ordinary serializable or externalizable objects. The serialized form of an enum constant consists solely of its name; field values of the constant are not present in the form. To serialize an enum constant, ObjectOutputStream writes the value returned by the enum constant's name method. To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; the deserialized constant is then obtained by calling the java.lang.Enum.valueOf method, passing the constant's enum type along with the received constant name as arguments. Like other serializable or externalizable objects, enum constants can function as the targets of back references appearing subsequently in the serialization stream.

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

因此,NonSerialized 是否可序列化并不会产生真正的影响。所以 FindBugs 没有在枚举中标记这一点是正确的。

如果我猜到的话,枚举中的字段通常是有效的最终值,并在类加载器加载枚举时进行初始化,所以也许他们认为序列化它们没有意义,接下来它们也可以再次初始化类加载器加载枚举的时间。这不是我知道的事情。

编辑:感谢 @TJR 提供的链接,以下 SpotBugs 问题相关(以及指向您的问题的链接):False positive SE_BAD_FIELD for non-transient non-serializable in an enum 。 SpotBugs 是 FindBugs 的继承者,基于 FindBugs 代码库构建并进一步开发。

关于java - FindBugs 不会提示枚举中的不可序列化字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39203642/

相关文章:

javascript - 如何显示 JavaScript 对象?

java - 从非 Activity 类获取资源

c# - 根据 bool 值更改标志

java - 操作对象、构造函数?

javascript - Java中模板引擎的目的是什么?

c# - 如何在C#中序列化一个对象并防止被篡改?

java - gson排除策略仅适用于目标对象的字段

Java - 子类型枚举或子类

java - 这是允许多个用户同时访问数据库的好方法吗?

java - RestTemplate Exchange 超时但 PostMan 可以工作