Given a class with a List field:
public class A implements Serializable {
private final List<String> names;
public A(List<String> names) {
this.names = List.copyOf(names);
}
// ...
}
The compiler issues a warning that the field is not serializable.
The unmodifiable list returned by List.copyOf
is serializable, so in reality it isn't a problem. But I want to get rid of the warning - what's the cleanest way to implement this?
Note: When the field doesn't need to be unmodifiable I could make it an ArrayList
(instead of List
) and copy the names in the constructor with new ArrayList(names)
(instead of List.copyOf(names)
). But then (obviously) the list is modifiable.
So I guess my question is: How do I declare an unmodifiable serializable List?
Java guarantees that the actual list implementations returned by List.of
and List.copyOf
are serializable (if their element type is serializable, obviously), so you don't need to do anything to make them serializable. The problem is that you declare the list variable as a List
, and that is not guaranteed to be serializable (List
itself does not extend Serializable
), so a warning is emitted.
There is no way to handle this other than to add a @SuppressWarnings("serial")
on the field (or class) because your implementation knows it always uses a serializable implementation.
The suggestion by wypieprz in the comments to use Collections.unmodifiableList
is not a good alternative because, although the actual type returned by this method also implements Serializable
, the actual serializability depends on whether or not the list passed in is serializable. You would then need to make a defensive copy anyway (checking if the passed in list implements Serializable
is not sufficient, because you could be receiving the return value of Collections.unmodifiableList
yourself). And if you need to make a copy, using List.copyOf
is a better choice.