I stumbled with an interesting case where i have something like this in the OnCreate method of my main activity:
val list = mutableListOf<TestObject.InnerObject> ()
val temp = TestObject.InnerObject
for (i in 0..15)
{
temp.id = i
Log.i ("id", temp.id)
list.add (temp)
}
for (element in list)
{
Log.i ("id", element.id)
}
TestObject is just this:
object TestObject {
object InnerObject {
var id = 0
}
}
Can someone explain to me why would the logs on the first for print correctly 0 to 15 but the logs in the second for are printing all equal ids?
CodePudding user response:
You are adding reference to the same variable in memory to list - in the end you have list of 16 identical objects.
First log function call shows you untruthfully valid behavior, because you are printing temporary value with every for loop iteration, but in second Log call you are printing final values. The same object must have the same values of the same field.
CodePudding user response:
You have an object, temp
, right? In the first loop, you're doing something to that object. Then you add it to the list - or to be more accurate, you add a reference to it to that list, something that points at your object.
Have a think about what the final list will look like. I'm gonna explain what's going on, but it's worth thinking about it first!
So you have your temp
object. It looks like it's an object
inside the TestObject
class, so just a single object. You're not creating any new instances of it, you're just working with the same object the whole time.
As you loop, you change the id
property on temp, and add temp to the list. This is a reference to the object, something that points at temp itself - it's not a new, separate copy of temp
. You're not creating a snapshot of its current state. There's one object, and a bunch of references all pointing to it.
So as you increment temp.id
, every item in your list will "see" that change - because every item is that specific object. You just have multiple references to it. When you finish (and when the second logging loop runs) you have 16 items, all that specific temp
object, whose id
value is now 15
.
You can probably work out the logging behaviour now! (I'm sure the question's already been answered anyway)
CodePudding user response:
object
keyword means creating a Singleton object - an object which has only one instance in a program. In the first cycle InnerObject.id
is changed for the same object and during that the logs print all the values. After the first cycle is finished the last value is set to InnerObject.id
that is 15. In the second cycle you just print that value.