If I clear() my local list (mList) it also clearing companion's Mutablelist (list)
Why this happening explanation's are welcome :)
I've a class with companion like this :
class Data {
companion object {
var list:MutableList<String> = ArrayList()
}
}
If I create my local list something like this :
fun main() {
// some dummy data
Data.list.add("Lion")
Data.list.add("Cat")
Data.list.add("Dog")
Data.list.add("Cheetah")
// my local mList
val mList = Data.list
println("Before Clearing : mList = $mList\n list = ${Data.list}")
mList.clear()
println("After Clearing : mList = $mList\n list = ${Data.list}")
}
OutPut
Before Clearing : mList = [Lion, Cat, Dog, Cheetah]
list = [Lion, Cat, Dog, Cheetah]
After Clearing : mList = []
list = []
As You can see in output if I clear() local mList it is clearing companion's list Why it is ?
if I do this same with some other things like double it is not happening like this example -
// same Data class's
...
var pi = 3.14
...
If change local mPi it doesn't change pi :
var mPi = Data.pi
println("Before Assigning to New value mPi = $mPi and pi = ${Data.pi}")
mPi = 319.12
println("After Assigning to New value mPi = $mPi and pi = ${Data.pi}")
2nd Output
Before Assigning to New value mPi = 3.14 and pi = 3.14
After Assigning to New value mPi = 319.12 and pi = 3.14
Link of Kotlin Playground
Why it is happening? I'd like to know :)
In order to understand what is going on here you need to know how values are saved in memory. All objects that are created using the
newkeyword (not needed in Kotlin), are stored in heap memory whereas all primitive data types are in stack memory.Consider the following code
What is happening here is that a new object of
ArrayListis being created in the heap. The variablelistcan be considered as a box which holds the location where the actual object is created. You can imagine the variable holding a value of0x7800abd12.Now what happens, when you create a new variable and assign the one that you created above.
Here, you assigned whatever value the variable
listhad to the variablenewList. What this did was in fact save the memory address0x7800abd12in the variablenewList. Remember, the value is the location where the actual list is created. Now, if the user accesses eitherlistornewList, they will be taken to the object at the given memory address. Since both variables have the same address, any change made to either of the two variables will reflect for both of them.But why doesn't this behaviour reflect when we are using primitive data types. Remember, I mentioned that primitive data types are stored on the stack rather than heap. Consider this example
In this case, the variable
piactually holds the value3.142rather than a memory location. Now, when you assign it to another variable, the new variable also holds the value rather than a memory location.Here
newPiholds the value3.142. If you changenewPito some other value, it will only update the variablenewPiand won't update the variablepi.In order to learn more about this you can check out this thread.