If you want to make an incompatible change you should change the serialVersionUID
so the you get an appropriate (if not nice) error instead of, say, a ClassCastException
at some point further on.
If you want to maintain compatibility, keep the serialVersionUID
and add a custom readObject
method to convert the List<CharSequence>
to List<String>
.
Edit: To expand on that, if you want compatibility, your code should look something like this:
// final - for one thing I don't want to implement readObjectNoData
public final class JeanObject {
If this class was added as a subclass to another class then there would be "no data" in legacy serialised streams.
private static final long serialVersionUID = 1L;
// Mutable field for Java Serialization, but treat as final.
private List<String> values = new ArrayList<>();
If you want values
to be final
you will need a degenerate Serialisation Proxy hack where the proxy object is of the same type.
I am going to assume you want the collection object to be mutable. You probably shouldn't serialise mutable objects, but that's how it's usually used and how the OP's example feels.
private void readObject(
ObjectInputStream in
) throws IOException, ClassNotFoundException {
ObjectInputStream.GetField fields = in.readFields();
@SuppressWarnings("unchecked")
var oldValues = (List<CharSequence>)fields.get("values", null);
// Don't bother with nice error message.
// NPE if missing or null elements.
this.values = oldValues.stream().collect(
ArrayList::new,
(values, value) -> values.add(value.toString()),
List::addAll
);
}
// ...
An alternative to the (very functional-looking) 3-arg Stream.collect
is to use Collectors.mapping
. An old-fashioned posh for loop would be less confusing all round, but that's not showing off on the internet - you'd look like someone who just gets stuff done.
Collectors.toList
is probably not suitable as, say, adding an elements to the list someway down the line may result in an error. Maybe not today. Maybe not tomorrow. But when your successor's automatic updates the implementation. And they will hate you for the rest of their life. Here's the API docs talking:
There are no guarantees on the type, mutability, serializability, or
thread-safety of the List
returned
Who wants that?
Edit: Reading that quote again, you might not be able to serialise your deserialised object if you use toList
...
(Code compiles but, as ever, is untested.)