简体   繁体   English

FindBugs不抱怨枚举中的不可序列化字段

[英]FindBugs not complaining on non-serializable fields in enums

If I have classes: 如果我有课:

class NonSerializable {
}

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

FindBugs raises violation FindBugs引发违规

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

and this looks correct. 这看起来是正确的。

However, when I change the code to be: 但是,当我将代码更改为:

class NonSerializable {
}

enum CanSerialize {
    INSTANCE;
    public NonSerializable nonSerializable;
}

FindBugs doesn't complain anymore. FindBugs不再抱怨。 Is it bug in FindBugs or it's safe to have non-transient, non-serializable fields in enums? 是FindBugs中的bug还是枚举中包含非临时性,不可序列化的字段是安全的?

On one hand, the answer to your question is it's safe to have non-transient non-serializable fields in an enum. 一方面,您的问题的答案是在枚举中包含非临时性不可序列化字段是安全的。 On the other, they don't get serialized when the enum does. 另一方面,枚举时不会序列化它们。 So even if they are not declared transient, they work sonewhat like transient fields nevertheless. 因此,即使未声明它们为瞬态,它们也仍然像瞬态字段一样工作。

From the Java Object Serialization Specification: 根据Java对象序列化规范:

1.12 Serialization of Enum Constants Enum constants are serialized differently than ordinary serializable or externalizable objects. 1.12枚举常量的序列化枚举常量的序列化与普通的可序列化或可外部化的对象不同。 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. 为了序列化枚举常量,ObjectOutputStream写入由枚举常量的name方法返回的值。 To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; 为了反序列化枚举常量,ObjectInputStream从流中读取常量名称。 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. 然后,通过调用java.lang.Enum.valueOf方法,将常量的枚举类型与接收到的常量名称一起作为参数来获取反序列化的常量。 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 ) http://docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/serial-arch.html#enum

So whether NonSerializable was serializable or not wouldn't really make a difference. 因此,无论NonSerializable是否可序列化,都不会真正NonSerializable So FindBugs is correct in not flagging this in an enum. 因此,FindBugs在不将其标记为枚举中是正确的。

If I may guess, fields in an enum are very often effectively final and initialized when the enum is loaded by the classloader, so maybe they figured that there was no point in serializing them, they can be just as well initialized again next time the enum is loaded by the classloader. 如果我猜得出来,枚举中的字段通常是由类加载器加载时有效地完成并初始化的,所以也许他们认为序列化没有任何意义,下次再次枚举时也可以很好地对其进行初始化由类加载器加载。 It's not something I know. 我不知道

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM