I have a Java serialization question that is neither reported nor negated as problematic in Java Docs (for JDK8).
So, suppose I have a class that implements Serializable
private static final long serialVersionUID = 1L;
private List<CharSequence> values;
If I change values
to
private List<String> values;
should I change the serialVersionUID
?
Another way to think of this serialization/deserialization operation is that it's a bit like casting.
Can you cast a List<CharSequence>
to a List<String>
? Not directly: the compiler will stop you, because generics are invariant. You can force it, however:
List<String> list = (List<String>) (List<?>) listOfCharSequences;
String entry = list.get(0);
and this might work a lot of the time, because, String
is the most common CharSequence
.
But it's possible that there's something else in there which is a CharSequence
, but not a String
, for example a StringBuilder
. The code above would crash with a ClassCastException
.
So, if you can be sure that all of your CharSequence
s are genuinely String
s, it's safe to make this change. Otherwise, you should either guard against it by changing the serial version id; or, in the case of String
, you could simply invoke toString()
on all of the elements:
List<String> listOfStrings = listOfCharSequences.stream()
.map(cs -> Objects.toString(cs, null))
.collect(toList())
(String.toString()
returns itself, so this would return no new instance for elements that are already String
s)