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 :)
CodePudding user response:
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 new
keyword (not needed in Kotlin), are stored in heap memory whereas all primitive data types are in stack memory.
Consider the following code
val list: MutableList<String> = ArrayList()
What is happening here is that a new object of ArrayList
is being created in the heap. The variable list
can be considered as a box which holds the location where the actual object is created. You can imagine the variable holding a value of 0x7800abd12
.
Now what happens, when you create a new variable and assign the one that you created above.
val newList = list
Here, you assigned whatever value the variable list
had to the variable newList
. What this did was in fact save the memory address 0x7800abd12
in the variable newList
. Remember, the value is the location where the actual list is created. Now, if the user accesses either list
or newList
, 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
val pi = 3.142
In this case, the variable pi
actually holds the value 3.142
rather than a memory location. Now, when you assign it to another variable, the new variable also holds the value rather than a memory location.
val newPi = pi
Here newPi
holds the value 3.142
. If you change newPi
to some other value, it will only update the variable newPi
and won't update the variable pi
.
In order to learn more about this you can check out this thread.