Effective Kotlin: Item 13 — Override clone judiciously

With Effective Java’s item 13 on cloning, it is clear to me that Joshua Bloch’s advice is to avoid the complexities of the clone method. Indeed, he suggests “a better approach to object copying is to provide a copy constructor or copy factory”.

Kotlin has taken this advice from Effective Java with the implementation of a copy function when you create a data class. copy creates a new instance with the default constructor, avoiding a lot of the complexities of clone while additionally allowing overriding of any of its properties.

It is essential to understand how copy works, with reference types it is merely copying the reference to the object and not copying the content. Consider the following code:

data class Object(val list: List<Int>)

val list = mutableListOf(1)
val alex = Object(list)

val bob = alex.copy()

list.add(2)

println(alex.list)
println(bob.list)

Although the class of list may look immutable, you can, of course, provide any type including mutable lists. Given that copy copies the reference when the mutable list changes we will see that both objects now contain [1, 2].

As with clone, be careful when dealing with mutable classes such as lists, and builders. Copy only works well on entirely immutable objects.

Each week I am looking at “items” from Joshua Bloch’s well-respected book, Effective Java to see how it applies to Kotlin. You can find the rest of the items I’ve covered at Effective Kotlin. Please let me know your thoughts.

Matt Dolan has been eating doughnuts and developing with Android since the dark days of v1.6.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store