タイトルの通りなんですが、JetBrainsさんが公式で
とか書いているおかげで信じている人もいるかもしれません。ですが、それは正しくありません。
試しに、次のコードをコンパイルしてみましょう。
fun double(x: Int?): Int = x?.let{ it * it } ?: 0
クラスファイル BoxingKt.class が生成されるので、javapしてみましょう。
Compiled from "Boxing.kt"
public final class BoxingKt {
public static final int foo(java.lang.Integer);
Code:
0: aload_0
1: dup
2: ifnull 21
5: astore_1
6: nop
7: aload_1
8: checkcast #9 // class java/lang/Number
11: invokevirtual #13 // Method java/lang/Number.intValue:()I
14: istore_2
15: iload_2
16: iload_2
17: imul
18: goto 23
21: pop
22: iconst_0
23: ireturn
}
まず、引数の型がjava.lang.Integerになっています。これは、引数を渡す時にBoxingのコストが発生することを意味します。また、その値を使って計算する場合、Unboxingのコストが発生します。
この問題は、プリミティブな型をnullableにしたときに発生します。ジェネリクスでプリミティブ型相当を引数にしたときにBoxingが発生するのと理屈は同じです。
必ずしもこの点が問題にはならないとは思いますが、一般にKotlinのnullable typeがzero overheadというのは嘘だと言って良いでしょう。