I implemented various times copy and deep copy. Didn't use clone a lot so decided to investigate it. I have class:
data class CountryResponse(var data: List<CountryData>): Cloneable {
public override fun clone(): Any {
return super.clone()
}
override fun toString(): String {
return "CountryResponse(data='$data')"
}
}
As you can see I already implemented Cloneable
. In my code I do:
var test = (CountryResponse(
listOf(
CountryData(null, nation = "", year = 3, population = 4),
CountryData(null, nation = "", year = 3, population = 3)
)
))
var copyOfTest = test.clone()
After this I debug. In my debugger copyOfTest and test have different references. So shallow copy is done. But when I try to check references for "data" they are same. This means that deep copy is not done.
(I implemented Cloneable
also in CountryData
data class).
How to achieve deep copy with cloneable? Also what is preferrable/better to use, are there any advantages. If Cloneable
has so much code, implementing it in data classes, etc, it looks easier for me to do deep copy and not bother with cloneable ever again:
var copyOfTest = test.copy(data = test.data.map { it.copy() })
Thanks
Object#clone
is supposed to be a shallow copy. It just creates a new object of the same type with the same (reference equality) fields
If you want to create a deep clone using that method, you need to add custom logic, e.g.:
public override fun clone(): Any {
val ret = super.clone()
ret.data = ArrayList(ret.data)
return ret
}