What is the difference between Array<Int> and IntArray in Kotlin, and why does it matter?
answer
- Array<Int> = Integer[] (boxed)
- IntArray = int[] (unboxed)
- primitive = less memory, better cache, no boxing
- not subtypes of each other
- convert via toTypedArray / toIntArray
basics
~10 sArray<Int> stores boxed Integer objects; IntArray stores raw int values directly. IntArray uses less memory and is faster because it skips the boxing, so prefer it for numbers.
solid answer
~40 sOn the JVM, Array<Int> compiles to Integer[] — each element is a boxed object with pointer and object overhead. The specialized primitive arrays (IntArray, LongArray, DoubleArray, FloatArray, ShortArray, ByteArray, CharArray, BooleanArray) compile to native int[], long[], etc., storing unboxed primitives contiguously. That means lower memory, better cache locality, and no boxing/unboxing churn in hot loops. Create them with intArrayOf(1,2,3) or IntArray(size) { it }. They share the same [] indexing, .size, and most stdlib operators with Array<T>. The cost: a primitive array is NOT an Array<Int> — they are unrelated types, so a function taking Array<Int> won't accept an IntArray. Convert with toTypedArray() (primitive -> boxed) or toIntArray() (boxed -> primitive). Prefer primitive arrays for numeric data and performance-sensitive code.
code
kotlin · 6 linesval boxed: Array<Int> = arrayOf(1, 2, 3) // Integer[]
val prim: IntArray = intArrayOf(1, 2, 3) // int[], no boxing
fun needsBoxed(a: Array<Int>) {}
// needsBoxed(prim) // won't compile
needsBoxed(prim.toTypedArray()) // convert int[] -> Integer[]go deeper
Knows IntArray exists and is the right choice for numbers, even if the boxing reasoning is fuzzy.
Explains boxed Integer[] vs unboxed int[], the memory/perf consequence, and that the two are not interchangeable types.
Adds cache-locality and GC reasoning, the nullability limitation, and the precise conversion functions and Java interop mapping.
Sets a default policy (List/primitive arrays for numerics) and weighs micro-optimization against readability across a codebase.
## Two distinct families Kotlin has two array families that look similar but compile very differently: - **`Array<T>`** — the generic array. For `Array<Int>` the JVM erases the generic to **`Integer[]`**: every element is a **boxed** object (an `Integer` instance on the heap, with header + pointer overhead). - **Primitive arrays** — `IntArray`, `LongArray`, `DoubleArray`, `FloatArray`, `ShortArray`, `ByteArray`, `CharArray`, `BooleanArray`. Each maps to the native JVM array `int[]`, `long[]`, `double[]`, etc., storing **unboxed** primitive values packed contiguously. ## Why it matters: boxing **Boxing** wraps a primitive (`int`) into an object (`Integer`). `Array<Int>` forces boxing of every element, costing: - Extra heap memory (object header + reference per element). - Pointer indirection and worse CPU **cache locality**. - Allocation/GC pressure and unbox/rebox work in tight loops. A primitive array avoids all of this — values sit inline, ideal for numeric crunching, buffers, and hot paths. ```kotlin val boxed: Array<Int> = arrayOf(1, 2, 3) // Integer[] val prim: IntArray = intArrayOf(1, 2, 3) // int[] val gen = IntArray(4) { it * it } // [0, 1, 4, 9] ``` ## They are NOT the same type `IntArray` is **not** a subtype of `Array<Int>`. A parameter typed `Array<Int>` will reject an `IntArray` and vice versa: ```kotlin fun sum(xs: Array<Int>) = xs.sum() val p = intArrayOf(1, 2) // sum(p) // compile error sum(p.toTypedArray()) // OK: int[] -> Integer[] val back: IntArray = arrayOf(1, 2).toIntArray() // Integer[] -> int[] ``` ## Shared API Both support `[]` get/set, `.size`, `.indices`, `for` loops, and most stdlib extensions (`map`, `filter`, `sum`, `sorted`). Differences are about element typing, not the surface operations. ## Rule of thumb Use a **primitive array** for numeric/perf-sensitive data. Use `Array<T>` for reference types or when you genuinely need an `Array<Int>` (e.g. nullability `Array<Int?>`, which primitive arrays cannot express).
- Can you have an IntArray of nullable ints?No. Primitive arrays hold unboxed primitives and cannot store null. For nullable ints you need Array<Int?>, which boxes.
- Does the choice affect interop with Java?Yes. IntArray maps to int[] and Array<Int> to Integer[]; Java APIs expecting int[] require IntArray (or a conversion).
Array<Int> is a box of numbers each in its own gift-wrapped parcel; IntArray is the numbers printed straight onto a ruler — no wrapping to unpack.
saying these in an interview costs you the question
- Saying IntArray is a subtype of Array<Int>
- Claiming there is no performance difference
- Thinking IntArray can hold null
- Not knowing the conversion functions toTypedArray/toIntArray
- Confusing the element-typing difference with a difference in the [] API