Kotlin 的 IntArray vs Array < Int >

我不知道在 Kotlin IntArrayArray<Int>有什么区别,也不知道为什么我不能把它们互换使用:

missmatch

我知道当针对 JVM时,IntArray翻译成 int[],但是 Array<Int>翻译成什么?

此外,你也可以有 String[]YourObject[]。为什么 Kotlin 有 {primitive}Array类型的类,而几乎任何东西都可以排列成一个数组,而不仅仅是原语。

31275 次浏览

Arrays in Kotlin are classes (not "special" types like Java).

Kotlin's stdlib provides special purpose classes for JVM primitive arrays in order to improve Java language integration and performance.

The rule of thumb would be to use Array<T> except if it cause a problem when mixing with existing Java code, or should be called from Java classes. For the record, I never had to use IntArray.

You can check the Language's documentation regarding this matter here: https://kotlinlang.org/docs/reference/basic-types.html#arrays

Array<Int> is an Integer[] under the hood, while IntArray is an int[]. That's it.

This means that when you put an Int in an Array<Int>, it will always be boxed (specifically, with an Integer.valueOf() call). In the case of IntArray, no boxing will occur, because it translates to a Java primitive array.


Other than the possible performance implications of the above, there's also convenience to consider. Primitive arrays can be left uninitialized and they will have default 0 values at all indexes. This is why IntArray and the rest of the primitive arrays have constructors that only take a size parameter:

val arr = IntArray(10)
println(arr.joinToString()) // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

In contrast, Array<T> doesn't have a constructor that only takes a size parameter: it needs valid, non-null T instances at all indexes to be in a valid state after creation. For Number types, this could be a default 0, but there's no way to create default instances of an arbitrary type T.

So when creating an Array<Int>, you can either use the constructor that takes an initializer function as well:

val arr = Array<Int>(10) { index -> 0 }  // full, verbose syntax
val arr = Array(10) { 0 }                // concise version

Or create an Array<Int?> to avoid having to initialize every value, but then you'll be later forced to deal with possible null values every time you read from the array.

val arr = arrayOfNulls<Int>(10)

It is worth noting that using the spread (*) operator on a vararg will return an IntArray. If you need an Array<Int>, you can convert your IntArray using .toTypedArray().