skip to content

When you call a Java method that takes an int[] from Kotlin, what Kotlin type do you pass, and why not Array<Int>?

level: juniorimportance: must knowfreq 70%

answer

  1. int[] -> IntArray, not Array<Int>
  2. Array<Int> == Integer[] (boxed)
  3. Specialized arrays = unboxed primitives
  4. intArrayOf / toIntArray / toTypedArray
  5. String[] -> Array<String>

basics

~10 s

Use Kotlin's IntArray for a Java int[]. Array<Int> is an array of boxed Integer objects (Integer[]), which is a different Java type and won't match an int[] parameter.

solid answer

~30 s

Kotlin maps Java primitive arrays to dedicated specialized classes: int[] -> IntArray, long[] -> LongArray, double[] -> DoubleArray, boolean[] -> BooleanArray, char[] -> CharArray, byte[] -> ByteArray, short[] -> ShortArray, float[] -> FloatArray. These hold unboxed primitives, so they compile down to the JVM primitive array (int[], etc.) and carry no boxing overhead. Array<Int>, by contrast, compiles to Integer[] (boxed). A Java method whose parameter is int[] therefore accepts IntArray, not Array<Int>. Build them with intArrayOf(1, 2, 3) or IntArray(size) { it }. Object/reference Java arrays (String[], Object[]) map to Array<String>, Array<Any?>, etc.

code

kotlin · 7 lines
kotlin
// Java: static int sum(int[] xs)
val xs: IntArray = intArrayOf(1, 2, 3)
val total = JavaMath.sum(xs)          // OK

val boxed: Array<Int> = arrayOf(1, 2, 3)
// JavaMath.sum(boxed)               // compile error: Integer[] != int[]
val fixed = JavaMath.sum(boxed.toIntArray())  // convert first

go deeper

for a junior

Knows to use IntArray for int[] and can build one with intArrayOf.

for a middle

Explains the boxing difference (Integer[] vs int[]) and the conversion functions toIntArray/toTypedArray.

for a senior

Articulates why generics force Array<T> to be a reference array on the JVM and the performance implications of boxing.

for a principal

Reasons about when specialized arrays matter for hot paths/memory and how API designers should expose them to keep Java callers boxing-free.

## The two kinds of arrays in Kotlin Kotlin deliberately splits arrays into two families to interoperate cleanly with the JVM: - **`Array<T>`** is a generic array of object references. Because the JVM erases generics but keeps array element types, `Array<T>` always compiles to a *reference* array. So `Array<Int>` becomes `java.lang.Integer[]` (each element is a **boxed** `Integer` object), and `Array<String>` becomes `String[]`. - **Specialized primitive arrays** (`IntArray`, `LongArray`, `DoubleArray`, `FloatArray`, `ShortArray`, `ByteArray`, `CharArray`, `BooleanArray`) compile directly to the JVM primitive arrays `int[]`, `long[]`, `double[]`, etc. They store **unboxed** primitives — no `Integer` wrappers, no per-element allocation. ## Why this matters for Java interop A Java API written as `void process(int[] data)` has a parameter of JVM type `int[]`. From Kotlin you must pass an `IntArray`, because only `IntArray` *is* an `int[]` at the bytecode level. Passing `Array<Int>` would mean handing over an `Integer[]`, which the JVM will not accept where an `int[]` is required — it is a different, incompatible type. The mismatch is caught at compile time. ## Construction ```kotlin // Java: void process(int[] data) val prim: IntArray = intArrayOf(1, 2, 3) process(prim) // OK: IntArray == int[] val sized = IntArray(5) { it * it } // [0,1,4,9,16] val boxed: Array<Int> = arrayOf(1, 2, 3) // Integer[] — does NOT fit int[] ``` ## Converting between the two - `Array<Int>.toIntArray()` — boxed to primitive. - `IntArray.toTypedArray()` — primitive to boxed `Array<Int>`. ```kotlin val p: IntArray = arrayOf(1, 2, 3).toIntArray() val b: Array<Int> = intArrayOf(1, 2, 3).toTypedArray() ``` ## Full mapping table | Java | Kotlin specialized | Kotlin generic | |------|--------------------|----------------| | `int[]` | `IntArray` | `Array<Int>` (= `Integer[]`) | | `long[]` | `LongArray` | `Array<Long>` | | `double[]` | `DoubleArray` | `Array<Double>` | | `boolean[]` | `BooleanArray` | `Array<Boolean>` | | `char[]` | `CharArray` | `Array<Char>` | | `byte[]` | `ByteArray` | `Array<Byte>` | | `String[]` | `Array<String>` | — | Rule of thumb: **primitive Java array -> specialized Kotlin array; object/reference Java array -> `Array<T>`.**

  • How do you turn an Array<Int> into something a Java int[] parameter accepts?
    Call .toIntArray() on it; that unboxes each element into a primitive int[].
  • Does IntArray have any boxing overhead when iterated?
    No — elements are primitive int, so iteration and indexing avoid Integer allocation, unlike Array<Int>.

IntArray is a crate of loose nails (primitives); Array<Int> is a crate of nails each in its own gift box (boxed Integers) — the machine that wants loose nails rejects the gift boxes.

saying these in an interview costs you the question

  • Claiming Array<Int> and IntArray are interchangeable for Java int[] parameters
  • Thinking Array<Int> compiles to int[]
  • Not knowing the specialized array classes exist
  • Confusing arrayOf with intArrayOf

context