Apart from the fundamental problems of Cloneable
there's another strong reason why one shouldn't make a record Cloneable
:
Records are inherently immutable. One of the biggest advantages of immutable classes is that one can stop worrying about object identity: any two objects with the same values can be used entirely interchangeable. The JavaDoc has a concept called Value-based Classes that goes a bit further (by disallowing public constructors and making any explicit use of object identity a mistake), but does describe the basic idea well.
Therefore creating a clone()
of a record would only ever produce a second object that for all intents and purpose should behave exactly the same as the original and can't ever change to behave differently (since records are immutable).
This suggests that there's no valid reason to clone()
a Record
.
And just for completeness sake: it is possible (but again, not suggested) to implement Cloneable
in a record:
record Foo(String a) implements Cloneable {
public Foo clone() {
try {
return (Foo) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("this can't happen", e);
}
}
}
Running this test code proves that a clone is actually created:
Foo original = new Foo("bar");
Foo clonedFoo = original.clone();
System.out.println(original + " / " + clonedFoo);
System.out.println(System.identityHashCode(original) + " / " + System.identityHashCode(clonedFoo));
produces this output:
Foo[a=bar] / Foo[a=bar]
670700378 / 1190654826
java.lang.Record
which constrains the behavior of the constructor+accessors+equals(), but if you can do all that, its OK. – MuoimuonClonable
is "just write a copy constructor instead." That's perfectly good advice for records too. – Muoimuon