Matthew Layton
Matthew Layton

Reputation: 42229

Kotlin - why do I get a KotlinNullPointerException

Consider the following code:

Example

fun main(args: Array<String>) {
    maybeWriteMessage()
}

fun maybeWriteMessage(message: String? = null) {
    writeMessage(message!!)
}

fun writeMessage(message: String) {
    println("Hello World")
}

Output

Exception in thread "main" kotlin.KotlinNullPointerException at com.series0ne.ApplicationKt.maybeWriteMessage(Application.kt:8) at com.series0ne.ApplicationKt.maybeWriteMessage$default(Application.kt:7) at com.series0ne.ApplicationKt.main(Application.kt:4)

This is because I'm passing message!! (null, damn it!) to a non-nullable parameter, however the parameter is never accessed.

Question

Why does Kotlin forcibly throw KotlinNullPointerException even when the null reference isn't accessed?

Upvotes: 15

Views: 30362

Answers (4)

d.felber
d.felber

Reputation: 5408

message: String? is indicating that message may or may not be null.

Since your function maybeWriteMessage has a default value of null for message and you are calling maybeWriteMessage() without specifying message - the default value (null) will be used when calling writeMessage(message!!).

As written in the documentation the !!-operator throws an exception when the value is null.

One way to trigger writeMessage safely would be to use .let:

fun maybeWriteMessage(message: String? = null) {
    message?.let { 
      writeMessage(it)
    }
}

Upvotes: 24

s1m0nw1
s1m0nw1

Reputation: 81859

In the following code:

fun maybeWriteMessage(message: String? = null) {
    writeMessage(message!!)
}

you're asserting that the nullable parameter message is not null by using !! (the not-null assertion operator). If message is null though, this will throw a null pointer.

TL;DR: Do not use !! unless you exactly know what you're doing. There's almost always a better way.

The !! Operator

The third option is for NPE-lovers: the not-null assertion operator (!!) converts any value to a non-null type and throws an exception if the value is null. We can write b!!, and this will return a non-null value of b (e.g., a String in our example) or throw an NPE if b is null:

val l = b!!.length

Thus, if you want an NPE, you can have it, but you have to ask for it explicitly, and it does not appear out of the blue.

Upvotes: 4

Michael
Michael

Reputation: 44090

From the documentation:

The !! Operator

The third option is for NPE-lovers: the not-null assertion operator (!!) converts any value to a non-null type and throws an exception if the value is null. We can write b!!, and this will return a non-null value of b (e.g., a String in our example) or throw an NPE if b is null:

val l = b!!.length

Thus, if you want an NPE, you can have it, but you have to ask for it explicitly, and it does not appear out of the blue.

So regardless of whether your function uses the parameter or not, by using message!!, you are explicitly asking for a NPE.

Upvotes: 2

Daria Pydorenko
Daria Pydorenko

Reputation: 1802

Operator !! throws an KotlinNullPointerException if message is null.

You can read about it here: https://kotlinlang.org/docs/reference/null-safety.html#the--operator

Upvotes: 6

Related Questions