3

I would need to have one class reference another. Not create a copy of it but have an actual reference to an already existing instance.

I might be able to explain it better with an example. Were we have a class Image:

class Image(imgPath: String) {
    val height   : Int
    val width    : Int
    val rgbMatrix: MutableList< MutableList< Triple<Int, Int, Int> > >

    /* ... etc. ... */
}

Now say I want a class ImageManager that only has a reference to an already existing Image:

class ImageManager(val img: Image) {
   /* ... */
}

So I can have this behaviour:

val image = Image("/res/images/image.png")

val imageManager = ImageManager(image)

// Setting the pixel at (125, 25) to black
imageManager.img.rgbMatrix[125, 25] = Triple(0, 0, 0)

// Should print the update value(0, 0, 0)
print( image.rgbMatrix[125, 25] )

My questions are:

  1. In Kotlin when does in assignment assign a reference and when does it assign a copy?

  2. How can I determine what kind of assignment happens when?

  3. Is there a part in the official docs where this is detailed? If there is I couldn't find it.

Thanks in advance!

Rares Dima
  • 1,575
  • 1
  • 15
  • 38
  • 1
  • @OliverCharlesworth I did not because my question is not about this particular case. It would of course be trivial to try *this* example, but in the larger project that I am working on getting to the state and conditions where I need this behaviour and testing it sufficiently would be extremely hard, so I am looking for a general answer :) – Rares Dima Mar 31 '18 at 08:51

1 Answers1

10

Similar to Java, Kotlin never implicitly copies objects on assignment. Variables always hold references to objects, and assigning an expression to a variable only copies a reference to the object, not the object itself.

Under the hood, each value is either a primitive (Int, Boolean, Char etc.) or a reference. When a value is assigned, the result is either a copy of the primitive, or a copy of the reference to the same object, which never leads to the referenced object being copied.

As far as I can tell, this behavior is not explicitly documented; instead, it is assumed to be the same to that in Java.

See also: Is Kotlin “pass-by-value” or “pass-by-reference”?

hotkey
  • 140,743
  • 39
  • 371
  • 326
  • Thank you! Now, is there a list of which types are primitive and which are not? I mean in java it is obvious, primitive types are not object, you just instantiate them like in C, but here, where there are no explicit primitive types... – Rares Dima Mar 31 '18 at 08:54
  • Actually, from the perspective of the type system and language, Kotlin does not have primitive types at all, they are mostly an implementation detail (see this [Q&A](https://stackoverflow.com/questions/45420806/are-kotlin-data-types-built-off-primitive-or-non-primitive-java-data-types)). You can check the list of the JVM primitive types to find out which types *can be optimized to primitives* on JVM (these are [numeric types](https://kotlinlang.org/docs/reference/basic-types.html#numbers), plus `Char` and `Boolean`). – hotkey Mar 31 '18 at 10:09