Slight suprise: varargs i: Int is an IntArray


I expected fun foo(varargs i: Int) to translate to void foo(java.lang.Integer... i), but it translates to void foo(int... i) and indeed the parameter is an IntArray and not an Array<Int>.

Nothing is wrong with this optimization, I just mention it because it slightly suprised me.

The bytecode Kotlin produces is now somewhat unique when you do method overloading.
Since JDK 7 the compiler would not allow you to do this:

void foo(int… i)

void foo(Object… o) // Allowed with JDK 6, ambiguous reference with JDK 7

The reason is simple:

As far as Kotlin and the JVM concerned it is all right to do it of course, so there is not much to talk about.


Maybe we should emit an error in this case too, but how does the overloading part relate to IntArray for "vararg i: Int"?


You can do this overloading in Kotlin:

fun foo(vararg i : Int) { }
fun foo(vararg o: Any) { }

The first method compiles to void foo(int… i).

foo(42) would invoke the most specific method, the first one.
Since there are only objects in Kotlin the compiler is allowed to select
the first as the most specific method.

void foo(int… i) { }

void foo(Object… o) { }

This is not something you can do in Java since JDK 7.

Instead you can only do this:

void foo(Integer… i) { }
void foo(Object… o) { }

As far as I know this doesn’t hurts interoperability with Java as long as one
remembers that Kotlin does this optimization on these built-in types.