Array<Int>
находится Integer[]
под капотом, а IntArray
это int[]
. Вот и все.
Это означает, что когда вы помещаете Int
в Array<Int>
, он всегда будет помещен в рамку (в частности, с Integer.valueOf()
вызовом). В этом случае IntArray
упаковки не произойдет, поскольку она преобразуется в примитивный массив Java.
Помимо возможных последствий для производительности из вышеперечисленного, следует также учитывать удобство. Примитивные массивы можно оставить неинициализированными, и они будут иметь 0
значения по умолчанию для всех индексов. Вот почему IntArray
и остальные примитивные массивы имеют конструкторы, которые принимают только параметр размера:
val arr = IntArray(10)
println(arr.joinToString())
Напротив, у Array<T>
него нет конструктора, который принимает только параметр размера: ему нужны действительные ненулевые T
экземпляры во всех индексах, чтобы они находились в допустимом состоянии после создания. Для Number
типов это может быть значение по умолчанию 0
, но нет способа создать экземпляры произвольного типа по умолчанию T
.
Поэтому при создании Array<Int>
вы можете использовать конструктор, который также принимает функцию инициализатора:
val arr = Array<Int>(10) { index -> 0 }
val arr = Array(10) { 0 }
Или создайте, Array<Int?>
чтобы избежать инициализации каждого значения, но позже вам придется иметь дело с возможными null
значениями каждый раз, когда вы читаете из массива.
val arr = arrayOfNulls<Int>(10)
Array<Int>
компилируется вInteger[]
(если компилятор не оптимизирует это)