Not-Null Assertion

The Not-Null Assertion and When to Avoid It

The not-null assertion !! turns a T? into a T by force, throwing a NullPointerException when the value is missing. It tells the compiler "trust me" and brings back the very crash null safety removes:

bang.kt: !! versus checkNotNullKotlin
data class Book(val id: Int, val title: String)
val catalog = listOf(Book(1, "The Quiet Harbor"))
fun find(id: Int): Book? = catalog.find { it.id == id }
fun main() {
    println(find(1)!!.title)                  // fine: book 1 exists
    try { println(find(99)!!.title) } catch (e: NullPointerException) { println(e) }
    val book = checkNotNull(find(99)) { "Book #99 is missing from the catalog" }
    println(book.title)
}
Output
The Quiet Harbor
java.lang.NullPointerException
Exception in thread "main" java.lang.IllegalStateException: Book #99 is missing from the
  catalog
   at BangKt.main(bang.kt:7)
   at BangKt.main(bang.kt)

A bare !! failure has no message. When a value must exist, say why: checkNotNull(x) { "..." } throws an IllegalStateException with your message (requireNotNull() an IllegalArgumentException, for arguments). Better still, handle absence with ?. and ?:. The open-source linter detekt (https://github.com/detekt/detekt 7,073 ) flags every !! through its UnsafeCallOnNullableType rule, on by default. For a property set after construction, such as one filled by a dependency-injection framework, lateinit var beats a nullable type plus !!.