How to handle a Findbugs "Non-transient non-serializable instance field in serializable class"?
However it is best practice to code against interfaces instead of concrete implementations.
I submit that no, in this case it is not. Findbugs quite correctly tells you that you risk running into a NotSerializableException
as soon as you have a non-serializable Set
implementation in that field. This is something you should deal with. How, that depends on the design of your classes.
- If those collections are initialized within the class and never set from outside, then I see absolutely nothing wrong with declaring the concrete type for the field, since fields are implementation details anyway. Do use the interface type in the public interface.
- If the collection are passed into the class via a public interface, you have to ensure that they are in fact
Serializable
. To do that, create an interfaceSerializableSet extends Set, Serializable
and use it for your field. Then, either:- Use
SerializableSet
in the public interface and provide implementation classes that implement it. - Check collections passed to the class via
instanceof Serializable
and if they're not, copy them into something that is.
- Use
I know this is an old question that's already answered but just so others know is that you can set the Set<Integer>
field as transient if you have no interest in serializing that particular field which will fix your FindBugs error.
public class TestClass implements Serializable {
private static final long serialVersionUID = 1905162041950251407L;
private transient Set<Integer> mySet;
}
I prefer this method instead of forcing users of your API to cast to your concrete type, unless it's just internal, then Michael Borgwardt's answer makes more sense.
You can get rid of those Critical
warning messages by adding the following methods to your class:
private void writeObject(ObjectOutputStream stream)
throws IOException {
stream.defaultWriteObject();
}
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException {
stream.defaultReadObject();
}