Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Kotlin "pass-by-value" or "pass-by-reference"?

Tags:

kotlin

As I know Java is pass-by-value from this post. I am from Java background I wonder what Kotlin is using for passing values in between. Like in Extensions or Methods etc.

like image 558
Rahul Khurana Avatar asked Jun 13 '17 07:06

Rahul Khurana


People also ask

Are kotlin variables references?

All data types in Kotlin are reference types.

How does kotlin pass a value to a function?

In Kotlin, You can pass a variable number of arguments to a function by declaring the function with a vararg parameter. a vararg parameter of type T is internally represented as an array of type T ( Array<T> ) inside the function body.

Is pass by value or pass by reference?

Pass by Value: The method parameter values are copied to another variable and then the copied object is passed, that's why it's called pass by value. Pass by Reference: An alias or reference to the actual parameter is passed to the method, that's why it's called pass by reference.


1 Answers

Every time I hear about the "pass-by-value" vs "pass-by-reference" Java debate I always think the same. The answer I give: "Java passes a copy (pass-by-value) of the reference (pass-by-reference)". So everyone is happy. I would say Kotlin does the same as it is JVM based language.

UPDATE

OK, so it's been a while since this answer and I think some clarification should be included. As @robert-liberatore is mentioning in the comments, the behaviour I'm describing is true for objects. Whenever your methods expect any object, you can assume that the JVM internally will make a copy of the reference to the object and pass it to your method. That's why having code like

void doSomething(List<Integer> x) {   x = new ArrayList<Integer>() }  List<Integer> x = Arrays.asList(1, 2, 3); doSomething(x); x.length() == 3 

behaves like it does. You're copying the reference to the list, so "reassigning it" will take no effect in the real object. But since you're referring to the same object, modifying its inner content will affect the outer object.

This is something you may miss when defining your attributes as final in order to achieve immutability. You won't be able to reassign them, but there's nothing preventing you from changing its content

Of course, this is true for objects where you have a reference. In case of primitives, which are not a reference to an object containing something but "something" themselves, the thing is different. Java will still make a copy of the whole value (as it does with the whole reference) and pass it to the method. But primitives are just values, you can't "modify its inner values". So any change inside a method will not have effect in the outer values

Now, talking about Kotlin

In Kotlin you "don't have" primitive values. But you "do have" primitive classes. Internally, the compiler will try to use JVM primitive values where needed but you can assume that you always work with the boxed version of the JVM primitives. Because of that, when possible the compiler will just make a copy of the primitive value and, in other scenarios, it will copy the reference to the object. Or with code

fun aJvmPrimitiveWillBeUsedHere(x: Int): Int = x * 2  fun aJvmObjectWillBeUsedHere(x: Int?): Int = if (x != null) x * 2 else 1 

I'd say that Kotlin scenario is a bit safer than Java because it forces its arguments to be final. So you can modify its inner content but not reassign it

fun doSomething(x: MutableList<Int>) {     x.add(2)                  // this works, you can modify the inner state     x = mutableListOf(1, 2)   // this doesn't work, you can't reassign an argument } 
like image 144
Alberto S. Avatar answered Sep 20 '22 04:09

Alberto S.