TIL: vararg in Kotlin is never nullable

Today I came across a piece of code that looked like this:

fun printAll(vararg names: String?) {
  names.forEach { name -> println(name) }
}

and noticed that the IDE did not complain about using names without checking if it is null names?.forEach { ... }!

After decompiling Kotlin’s bytecode I saw that no matter what type I use (String? or String) the java code was the same:

public static final void printAll(@NotNull String... languages) {
  //...
}

Does the Kotlin compiler ignore the nullable type completely? Turns out that yes!

And the reason is quite clear and straightforward but it hadn’t registered in my mind until now:

Note that vararg parameters are, as a rule, never nullable, because in Java there is no good way to distinguish between passing null as the entire vararg array versus passing null as a single element of a non-null vararg array.

kotlin’s forums

What if we pass a null value?

As a matter of fact if you pass a null value:

printAll(null)

the compiler makes sure that the java code will be called with a null value casted to the appropriate type:

printAll((String)null);

which ends up in an array of strings that has one element!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s