Unnecessary null check?


#1

Hello everyone, I’m using Ktor on IntelliJ and would like to know why do I need to null check on feed.first
Since the first thing I do is to check if first is null
Does it have to do with the Pair implementation?

typealias ErrorCode = Int
typealias Result<T> = Pair<T, ErrorCode>

val feed : Result<List<...>> = Database.getFeed(quantity)

if (feed.first != null) {
    when (feed.second) {
        HttpURLConnection.HTTP_NOT_FOUND -> call.respond(HttpStatusCode.NotFound)
    }
} else {
    call.respond(HttpStatusCode.OK, feed.first!!)
}

#2

The first thing you are doing is checking if first is not null

So in the if branch first is not null but in the else branch first is null

Just change the != to ==.


#3

Holy shit, you’re right.
This happened before, I feel bad for asking now…

Edit: I just changed my code and it says it must be checked because first is a public property on another module


#4

I’m assuming that you’ve got a typo and meant if (feed.second != null).

feed.second is a property. Accessing a property causes some code to run. This code usually returns the same value, but that’s not guaranteed. Compiler can’t rely on that behaviour. Getter could do anything including formatting your hard disk driver or launching nuclear attack. Therefore compiler can’t assume that second invocation of feed.second would return the same value. So even if you’ve checked that value to be not null, second invocation might return null and cause NullPointerExcetion and Kotlin tries to avoid that at all costs.

You can extract that value into another variable:

val feedSecond = feed.second

and then use it. Now compiler can be sure that this value won’t change between calls and smart cast will work.

Another option is just to use when:

when (feed.second) {
    HttpURLConnection.HTTP_NOT_FOUND -> call.respond(HttpStatusCode.NotFound)
    null -> call.respond(HttpStatusCode.OK, feed.first!!)
}