List ending with all elements being equal in Kotlin, interesting case

Issue

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?

Solution

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)

Answered By – cactustictacs

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published