Allocation of vararge with spread operator

I used an Android game framework which had a vararge method.
I called this method every frame.

 override fun update(){
     foo(a,b,c)
 }

I knew I don’t need a allocation here.
So I fixed it with spread operator like I used to do in Java.

val bar=arrayOf(a,b,c) //as a property
override fun update(){
    foo(*bar)
}

But when I checked it’s bytecode, I found it still called a Arrays.copyOf for bar.
I knew a copy here is for safe, but I couldn’t avoid this allocation at all.

I think it’s no need an array copy here
I searched some open sources written in Java, none of them change it’s array value of vararg.

What’s more, I found for none primitive type of vararg in Kotlin, it will be transformed to Array , which means it can’t be changed in normal way.

You can use a “List” instead of vararg.

Thanks, but was not solved my problem.
The vararg is in the library.
What’s more, my main point is no need a implicit Arrays.copyOf call for vararge with spread operator.

The fact that you didn’t find any code that changes the array does not mean that there is no such code. Kotlin has to guarantee correctness and safety of operations, and therefore the defensive copy is required.

1 Like

Thanks. But is there any way to avoid this defensive copy?

No, not at this time.

Thanks, But I still think this defensive copy is only required for beginners.:joy:

@yole @ilya.gorbunov Can we add an annotation to allow developers to skip the defensive copy? Right now, there’s no way to call a vararg Java method (esp. from a library where we can’t modify) from Kotlin without copying the array when we have an existing arary.