Kek
Kek

Reputation: 381

In Kotlin, if an object is passed into a new instance of a class and then some properties are changed, will it change in the original object?

The question is in the title: In Kotlin, if an object is passed into a new instance of a class and then some properties are changed, will it change the properties in the original object? Image I've got the following situation:

class User{
   var name: String = "initial name"
}
class UserHolder{
   companion object{
      var INSTANCE: User
   }
}
class ClassA{
   fun doStuff(){
       val classB = ClassB(UserHolder.INSTANCE)
       classB.changeUser()
       val newName = UserHolder.INSTANCE.name // is it "initial name" or "My new name"?
   }
}
class ClassB(private val user: User){
   fun changeUser(){
       user.name = "My new name"
    }
}

will the newName be is "initial name" or "My new name" and why? I know that if I pass an object into a method and change its properties, then on return the properties will be updated. But why doesn't it work with the classes? Is it because we write 'val user'?

Upvotes: 0

Views: 662

Answers (1)

leonardkraemer
leonardkraemer

Reputation: 6793

As described in the answers in Is Kotlin "pass-by-value" or "pass-by-reference"? when you pass an object to a function you pass a copy of the reference. Through this reference you are able to modify the passed object.

The reason you cannot modify Instance.name is because you declared User.name as val. val is for read-only properties that can not change and therefore can not be reassigned.

If you change it to var you can modify it. See https://try.kotlinlang.org/#/UserProjects/7t8j73oqdtiin3ja8atbdq15op/lhiik2ek7otonb3kklpk33jclg

class User{
   var name: String = "initial name"
}
class UserHolder{
   companion object{
      var INSTANCE : User = User()
   }
}
class ClassA{
   fun doStuff(){
       val classB = ClassB(UserHolder.INSTANCE)
       classB.changeUser()
       val newName = UserHolder.INSTANCE.name // is it "initial name" or "My new name"?
   }
}
class ClassB(private val user: User){
   fun changeUser(){
       user.name = "My new name"
    }
}

fun main(args : Array<String>){
    System.out.println(UserHolder.INSTANCE.name)
    val classA = ClassA()
    classA.doStuff()
    System.out.println(UserHolder.INSTANCE.name)
}

prints:

initial name
My new name

Upvotes: 3

Related Questions