How to copy an object
Short answer
The clearest way is a copy constructor that takes an object of the same class:
class Settings {
String theme;
int fontSize;
Settings(String theme, int fontSize) {
this.theme = theme;
this.fontSize = fontSize;
}
Settings(Settings other) {
this(other.theme, other.fontSize);
}
}
void main() {
var original = new Settings("dark", 14);
var copy = new Settings(original);
copy.fontSize = 18;
IO.println(original.fontSize + " " + copy.fontSize);
}Output:
14 18Records need no copying
An immutable object can be shared without copies. For a "modified copy", create a new object:
record Settings(String theme, int fontSize) {
Settings withFontSize(int size) {
return new Settings(theme, size);
}
}
void main() {
var original = new Settings("dark", 14);
IO.println(original.withFontSize(18));
IO.println(original);
}Output:
Settings[theme=dark, fontSize=18]
Settings[theme=dark, fontSize=14]A deep copy
If the object contains a mutable list, copy it too, otherwise both copies share one list:
class Playlist {
String name;
List<String> songs;
Playlist(String name, List<String> songs) {
this.name = name;
this.songs = songs;
}
Playlist(Playlist other) {
this(other.name, new ArrayList<>(other.songs));
}
}
void main() {
var original = new Playlist("Road", new ArrayList<>(List.of("Song A")));
var copy = new Playlist(original);
copy.songs.add("Song B");
IO.println(original.songs);
IO.println(copy.songs);
}Output:
[Song A]
[Song A, Song B]Common mistake
Assigning the object to another variable. It is not a copy: both variables point to the same object:
class Counter {
int value;
}
void main() {
var a = new Counter();
var b = a;
b.value = 10;
IO.println(a.value);
}Output:
10The clone() method exists too, but it is awkward: you need the Cloneable interface, a cast and exception handling. In new code use a copy constructor or records.
Functions used in this recipe
- record — Declares a record — an immutable data class with ready-made equals(), hashCode() and toString().
- List.copyOf() — Creates an unmodifiable list copy of a collection.
- Cloneable — A marker interface that allows Object.clone(). New code uses copy constructors instead.