view raw
Michal Kordas Michal Kordas - 7 months ago 48
Java Question

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

<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 {
public NonSerializable nonSerializable;

FindBugs doesn't complain anymore. Is it bug in FindBugs or it's safe to have non-transient, non-serializable fields in enums?


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:

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.


So whether NonSerializable was serializable or not wouldn’t really make a difference. So FindBugs is correct in not flagging this in an enum.

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.