The naive approach to have a record field that is a collection leads to mutable records, and I think that's something we don't want.
Do people generally ignore this aspect, or does one try hard to make the record truly immutable?
If the latter, what would one do?
The naive approach would be record Foo(List<String> bar) { }, and I guess people can do foo.bar().add(...) and similar things to mutate this “immutable” record.
The record constructor could clone the list, then make it unmodifiable, would that be sufficient?
record Foo(List<String> bar) {
Foo {
bar = new ArrayList<>(bar);
bar = Collections.unmodifiableList(bar);
}
}
I'm not sure if this leads to some other way where foo.bar() ends up being mutable after all.
All of the above can only work because String is immutable, I understand that we need to make sure that a record is only constructed of immutable things.
As far as the state of the list is concerned, this is enough for the record to be immutable. A test that proves it:
The list in
Foois equal to the initial list, changing initial list does not change list in record, and attempting to change list inFoothrows exception.Additionally you can simplify the record constructor, using
List.copyOf():