Nullpointerexception message

I guess Kotlin is helpless here. It simply throws java.lang.NullPointerException.

we should get valuable message of the exception. !! is a nice hack to bypass the checks but underneath outcome is same as Java

This is a place where kotlin depends on JDK version as right now I use 11 this would get solved if I upgrade to 14 (JEP 358: Helpful NullPointerExceptions)

kotlin 1.6
fun main() {
val a:String? = null
try{
println(a!!+"")
}catch(e: Exception) {
println(e.message)
}
}

Output: null

One of the nicest things about Kotlin is that it makes it very easy to handle nulls. I’d say JEP 358 is actually working around Java’s poor support for properly handling nulls.

In this particular example, you should be using the Elvis operator to properly handle the null condition, which is better than throwing an exception with a useful message that may break your code anyway.

@antenangeli.1

I think you are not talking on the point.

The point it Kotlin has !! operator which at runtime will throw java.lang.NullpointerException if the variable is found null. My concern is we don’t get proper message from the exception. It does the same like Java. We cannot use elvis everywhere where !! is to be used. if so then why would Kotlin have !!.

I have shown try catch just for understanding, in real code we don’t catch such statements.
so the statement would just be println(a!!+"") . We cannot use elvis here because the intention of a!! here is to say that throw exceotion if a is found null. Now when kotlin throws such exception it should include the detail like at which point and reason for the exception.

I agree with antenangeli.1.

Kotlin have perfect practice to avoid NPE, but in some conditions we must use nullable type.

If we stick to the rules of kotlin, we should use Elvis operator, the safe call operator or check null before we use the object with nullable type.

I treat !! as an assertation instead of an operator. The !! symbol indicates that we are sure about that this nullable object is not null here. But whatever we think, the compiler will check it to make sure the object is really not null.

If we got NPE by using !!, we should consider twice about the code logic, not focus on the helpful information. Our assertations fail!

1 Like

And refer to Kotlinlang.org, the !! operator dose have the name the not-null assertion operator.
Null safety | Kotlin (kotlinlang.org)

My opinion is somewhere in between. Descriptive error messages are always good to have, there is no reason to not implement them. On the other hand, this feature is of a very low importance to me. I don’t remember the last time I got NPE in Kotlin and even if that happens, it is usually very clear without a good message as there are very few places in the code where NPE may happen.

Also, !! is for pretty rare cases when we are sure a variable is not null, because there is some nullability logic that can’t be easily represented statically. We should avoid it if possible.

1 Like

As broot says, this is for rare cases — much rarer than Java, in which practically any access to a field or method or unboxing can potentially throw a NPE.

In Kotlin, !! is very rarely needed — to the point where its use is a code smell, and usually indicates there’s a better alternative. I can’t recall ever using it more than once on the same line; and so the line number in the stack trace will almost always identify the value that was null. And since (AIUI) that’s pretty much all the JEP adds, the benefit to Kotlin would be minimal — not a bad thing, but not worth much effort to implement.

(It might be a little more helpful if it also covered NPEs generated by using platform types or uninitialised lateinit properties, which are slightly less predictable — though again, a line number is almost always enough.)

The Elvis operator can be used to throw a better exception if you really want to, you can write something like this:

println((a ?: throw IllegalStateException("my variable a is null")) + "")

I still haven’t seen an actual case to use !! in production code. I use it sometimes in test assertion, but never on production code.

Note that it can be replaced with:

checkNotNull(a) { "my variable a is null" }

https://youtrack.jetbrains.com/issue/KT-46868

Though, I agree that in many cases it’s not so big a problem, because !! can be just avoided

I sometimes find myself fighting the urge to use something like this:

list.filter { it.someProperty != null }
    .map { SomeClass(it.someProperty!!, it.someOtherProperty) }

Working with immutable data, it’s 100% safe, but 95% ugly. Of course, it can be rewritten as

list.filter { it.someProperty?.let { someProperty to it } }
    .map { SomeClass(it.first, it.second.someOtherProperty) }

but it’s ugly too, and it can only be used with a single property. If I have to do it with two properties (e. g. it.startTime != null && it.endTime != null), it becomes even uglier, although it can be worked around by introducing a helper class combining the two properties together (it.timeInterval), which isn’t a perfect solution either.

Back on topic, I absolutely agree with this:

Indeed, NPEs are so rare in decent Kotlin code that it’s a feature that is nice to have, and at the same time is hardly missed at all.

@stachenov How would you code this scenario instead of !!.

fun main() {
val c = C(B(A(“a”)))
val msg2 = “kt”
val fullMsg = addMsg(
c.b?.a?.aMsg!!, //how to write this without !!
msg2
)
}

fun addMsg(msg: String, msg2: String) = msg+msg2

//db table Employee
class A(val aMsg:String?)
class B(val a:A?, val bMsg:String? = null)
class C(val b:B?, val cMsg:String? = null)

I guess you would suggest,

  1. let, but this is just like add extra code to get rid of not null in kotlin and adds more unnecessary code all around
    c.b?.a?.aMsg?.let{
    val fullMsg = test(
    it,
    msg2
    )
    }

  2. val fullMsg = addMsg(
    c.b?.a?.aMsg ?: throw Exception(),
    msg2
    )
    but this is same that inorder to excuse and tell kotlin that amsg is not null and excuse we should add redundant code all around

do you have better alternative?

And how do you know all these props can’t be null? And if they can’t be null then why they are nullable?

I think you misinterpret how you should handle nullable data types. If you have nullable variable with guaranteed not-null inside then the proper solution is to use !! indeed. But most of the time we should not really get into such situation. Not-null values should be typed as not-null, so the problem already occurred somewhere “earlier” in the code.

1 Like

Like this:

fun main() {
    val fullMsg = addMsg(
        ”a”,
        ”kt”
    )
}

In your example you know that the expression is not null because the “a” is hard coded. Then you might as well hard code “a” as the parameter directly.

I realize that your code is just an example but it still illustrates a good point about !!. You describe !! as an operator that can be used to throw NPE, but that is not its purpose. Its purpose it to tell the compiler that you know that a value will not be null. It shouldn’t be used in places where the expression could sometimes be null. Why would you declare properties as nullable and then use !!?

First, please format code properly by surrounding it with lines containing triple backticks, like this (remove the //):

// ```
// code goes here
// ```

Use single backticks for in-line code:

// Using `!!` is bad practice.

As it is in your posts, it’s barely readable.

Second, your question as it is has no answer, because it would depend on the context. Provide more realistic example to get a more realistic answer. In this particular case the best I can think of is to just use c.b?.a?.aMsg.toString().

There are several ways of dealing with nulls. A few examples:

  1. Consider the Null Object Pattern: instead of using null, make it non-nullable, and use some special value to indicate the property is missing, e. g. 0, "", "null", Instant.MIN, whatever.
  2. Make an extension function or property accepting a nullable receiver, or, if several properties can be null, the container object itself (and even that can be nullable as well!):
class LogMessage(
    val message: String,
    val exception: Throwable? = null
)

fun LogMessage?.format() =
    when {
        this == null -> "<no message>"
        exception == null -> message
        else -> "$message: $exception"
    }
  1. Make different classes: one with property, one without, e. g. LogMessage, ExceptionLogMessage.

None of these require !!, even wrapped inside a convenience function.

fun main() {
    //consider c is initialized with data from database. 
    val c = C(B(A(“a”)))
    val msg2 = “kt”
    addMsg(
        c.b?.a?.aMsg!!, //how to write this without !!
        msg2
    )
}

fun addMsg(msg: String, msg2: String) = msg+msg2

//db tables
class A(val aMsg:String?)
class B(val a:A?, val bMsg:String? = null) //here  a and bMsg can be null as related db column can be nullable
class C(val b:B?, val cMsg:String? = null) //here b and cMsg can be null as related db column can be nullable

@stachenov @broot
As stated above consider A, B and C are db models and so can their props be null. This is requirement.

Now, I have declared addMsg function to accept nonnull arg of type String because

  1. I don’t want to pass null value
  2. I have other method call with non-null values

Now the point is to pass I use c.b?.a?.aMsg!! as arg to addMsg as I know here in this case aMsg will be fetch as not null from db.
So I would like to get suggestion from you how can I avoid !! yet my code should be so simple.

Now, I know this can be done as below but the point is the code neither of them is as clean as c.b?.a?.aMsg!! . All I say is right now !! is working as required i,e. is in this case it throw java.lang.NullpointerException however this is like depending on jvm. it does not show the detail of the error.

1. addMsg(
        c.b?.a?.aMsg ?: throw IllegalArgumentException(),  //I don't like this because this boiler plate, I want clever language like kotlin to do this for me, like throw that exception when I do !! or so instead
        msg2
   )

2. c.b?.a?.aMsg?.let {   // I don't want to to this as I may use the result somewhere or for some other reason.
        addMsg(
          it,
          msg2
       )
    }

Ok, but if these props are fetched from the db and they can be null in the db, then how do you know that they aren’t? You should use !! only if you are sure you deal with not-null value. If you aren’t certain about it then you should handle this possible null value one way or another. You can provide a replacement value (e.g. using ?:), you can provide an alternative action (if or ?:), you can just skip the action (?.let), but you should not use !! in that case, because it will throw NPE from time to time, which basically means that your code is bugged.

@broot That what I mentioned. in this method main aMsg will always be not null, as specific query will fetch not null value. like employee table can have null hobby but if i query employee with hobby with not null hobby I would be sure right?

The point is why can’t !! throw some custom kotlin Nullpointerexception with message instead of simply relying on jvm?

So you know it’s not null because you’ve filtered nulls out. Yes, that’s one annoying limitation of Kotlin’s null-safety, applicable not only to DB queries, but also to code like

list.filter(it.property != null)
    .map { /* use it.property here */}

This is really annoying, and there is no perfect solution. Possible work-around are:

  1. Use !!. Ugly, and the resulting exception is non-informative.
  2. Use some an Optional-like class instead of nullable. Too much boilerplate.
  3. Use some other method or property for accessing the non-nullable value of a nullable property, like getMessageOrThrow() or getNonNullMessage(). Ugly, boilerplate and it’s rather hard to invent an elegant name for such a property or function.

At the moment, I’m not aware of an easy and elegant solution. And I can’t even imagine what it would look like if there was one… After all, Kotlin just threw its null-safety features over a platform that had no null-safety support at all, so it isn’t very surprising that it hasn’t succeded in every possible scenario. On the contrary, I think it’s rather amazing that it actually does a very good job of keeping the code null safe except for a few edge cases like this.

1 Like

Ah, I took while to be on track. I was crazy when you said Yes, this scenario is not so edge its very common for every app connecting with database. Since, I am now convinced that there is no better way to write elegant code than !!, I will prefer ?: throw Exception() instead of !! even though it pollutes my code for now as I don’t get detail message. As I said, if we use !! with jvm 14, it would throw error with message as jvm has fixed it, I am right now using 11 so not so far.

Kotlin is not a language which makes us code not null because it lives on top of Java but it's a language which help dealing with nulls with such exceptions.