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[](если компилятор не оптимизирует это)