How to pass Kotlin Array to Java varargs: a complete guide for beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Kotlin Array to Java varargs: how not to break compatibility and write clean code

\n\n

Have you ever written code in Kotlin, called a good old Java method with varargs — and suddenly got a compilation error? If so, you are not alone. The question "Convert Kotlin Array to Java varargs" on Stack Overflow has thousands of views. And it's not surprising: at the intersection of two languages, non-obvious nuances often arise.

\n\n

In this article, we will break down how to correctly pass a Kotlin array to a Java method with a variable number of arguments. You will learn what the spread operator is, why Array<String> is not equal to String..., and how to avoid typical mistakes. Let's go!

\n\n

What are varargs in Java and why are they needed

\n\n

First, let's recall the basics. Varargs (variable-length arguments) is a Java mechanism that allows you to pass an arbitrary number of arguments of the same type to a method. Syntactically, it is denoted by an ellipsis after the type:

\n\n
public void printMessages(String... messages) {\n    for (String msg : messages) {\n        System.out.println(msg);\n    }\n}
\n\n

You can call this method like this:

\n\n
printMessages("Hello");\nprintMessages("Hello", "World");\nprintMessages(); // an empty call also works
\n\n

Inside the method, the arguments are represented as an array String[]. But from the outside, it's just a set of values separated by commas. Convenient, right?

\n\n

Now imagine you have a Kotlin Array and you want to pass it to such a Java method. Naive code won't work:

\n\n
val messages = arrayOf("Hello", "World")\nprintMessages(messages) // Compilation error!
\n\n

Why? Because Kotlin is stricter with types. The Java method expects String..., but you are passing Array<String>. These are different things. The compiler sees the mismatch and throws an error.

\n\n

Solution: the spread operator (* operator)

\n\n

In Kotlin, for such cases, there is the spread operator — an asterisk * before the array. It literally "unfolds" the array into individual elements, which are then passed as varargs.

\n\n
val messages = arrayOf("Hello", "World")\nprintMessages(*messages) // Works!
\n\n

Everything ingenious is simple. But let's break down how it works under the hood.

\n\n

How the spread operator transforms types

\n\n

When you write *messages, Kotlin:

\n
    \n
  • Takes each element of the array
  • \n
  • "Extracts" them from the Array wrapper
  • \n
  • Passes them as separate arguments to the Java method
  • \n
\n\n

For the Java method, it looks as if you wrote printMessages("Hello", "World"). No arrays — just plain strings.

\n\n

An important nuance: the spread operator only works with Array (and some other collections via toTypedArray()). You cannot unfold a regular List this way.

\n\n

Typical mistakes and how to avoid them

\n\n

Even knowing about the spread operator, beginners often make mistakes. Here are the most common ones.

\n\n

Mistake 1: Passing an array without the asterisk

\n\n
// Incorrect:\nval numbers = intArrayOf(1, 2, 3)\nsomeJavaMethod(numbers) // Error\n\n// Correct:\nsomeJavaMethod(*numbers.toTypedArray())
\n\n

Note: for primitive types (IntArray, DoubleArray, etc.), you first need to convert to Array using .toTypedArray(). The spread operator only works with object arrays.

\n\n

Mistake 2: Confusion with List

\n\n

Many try to pass a List<String> directly:

\n\n
val list = listOf("A", "B")\nprintMessages(*list) // Error! List != Array
\n\n

Solution: first convert the list to an array:

\n\n
printMessages(*list.toTypedArray())

Blogs

Book Recommendations