323

I'm converting Java to Kotlin with Android Studio. I get double bang after the instance variable. What is the double bang and more importantly where is this documented?

mMap!!.addMarker(MarkerOptions().position(london).title("Marker in London"))
hotkey
  • 140,743
  • 39
  • 371
  • 326
mbr_at_ml
  • 3,585
  • 2
  • 13
  • 12

7 Answers7

376

This is unsafe nullable type (T?) conversion to a non-nullable type (T), !! will throw NullPointerException if the value is null.

It is documented here along with Kotlin means of null-safety.

Simson
  • 3,373
  • 2
  • 24
  • 38
hotkey
  • 140,743
  • 39
  • 371
  • 326
  • 8
    what does it mean when the `!!` is at the end of a statement? IJ auto-convert to Kotlin did that for me `val price = sale.latest!!` – ycomp Feb 23 '16 at 16:57
  • 27
    @ycomp, it means that `sale.latest` can contain `null`; the assignment will succeed only if `sale.latest` is not null and will throw NPE otherwise. This gives null-safety for `val price`: its type will be non-null. See https://kotlinlang.org/docs/reference/null-safety.html – hotkey Feb 23 '16 at 17:46
  • 2
    @hotkey: So what is the difference between getting NPE - here OR when latest method is accessed on null object? – Aada Aug 13 '18 at 12:12
  • 7
    @Aada, it's common problem to debug an NPE and have a hard time locating the line / execution path that set the value to null. This null assignment could happen on a different context, class or even day! By using `!!` you can fail-fast and locate the root cause of a NPE. I wish Java had a similar feature (that is, w/o ugly `if` statements and/or `assert`ions). – Tasos P. Jan 11 '19 at 13:09
  • As Kotlin is Null safe programming language, to prevent throwing `NullPointerException` , use `let`. `T?.let{ it.addMarker() } `. By this way, you are safe. – Parisa Baastani Dec 08 '20 at 11:53
  • @ParisaBaastani The question is if that null is a valid state for your program or something went wrong and you now have a program not crashing, but not working properly. If you architected something to never be null, the double-bang is part of the fail-fast principle where you assert this will never happen and if it does, the stacktrace will be helpful and you can easily repair the issue instead of never finding the issue because the code just ignores it. – Arno Schoonbee Oct 21 '22 at 09:20
129

Here is an example to make things clearer. Say you have this function

fun main(args: Array<String>) {
    var email: String
    email = null
    println(email)
}

This will produce the following compilation error.

Null can not be a value of a non-null type String

Now you can prevent that by adding a question mark to the String type to make it nullable.

So we have

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email)
}

This produces a result of

null

Now if we want the function to throw an exception when the value of email is null, we can add two exclamations at the end of email. Like this

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email!!)
}

This will throw a KotlinNullPointerException

CoolMind
  • 26,736
  • 15
  • 188
  • 224
Alf Moh
  • 7,159
  • 5
  • 41
  • 50
  • 9
    So, why would people use '!!' even though it is unsafe because an app will be terminated when that variable has null? – Wood Sep 03 '18 at 14:59
  • 4
    @david you can use it only when you are 100% sure that the variable is not null (e.g. you explicitly checked it) and you need non-nullable variable – FMK Sep 13 '18 at 08:53
  • 11
    @FMK I get it, thanks! I understand that double bang is used to make it possible that the values of nullable type variable to go into non-nullable types variable, right? – Wood Sep 13 '18 at 09:26
  • 2
    @david yes, exactly. – FMK Sep 13 '18 at 10:35
  • 4
    I get the reasoning, but if you think about it, if we know that the value of a variable will not be null and we are 100% sure of the fact, then to use a '!!' is in theory 100% of no use as we already are 100% sure that the variable in question will not be null, ever. Surely the usage is when we are not 100% sure that the variable in question may be null and we want an error to be thrown if it is null so we can fix the root cause? – Jeremy Feb 04 '21 at 21:34
  • 1
    @Jeremy That is not always the case. In Android for example there is a lot of interaction with Java frameworks that do not have non-null types in the same way and type-unsafe data structures such as bundle arguments. If you have a fragment for example with a private constructor and a factory function that always inserts a bundle argument, then when fetching that argument in the fragment you can use the double-bang since there is literally no way to create the fragment without it adding that argument. – Arno Schoonbee Oct 21 '22 at 09:24
35

Not-null assertion operator

Kotlin's double-bang operator is an excellent sample for fans of NullPointerException (NPE).

The not-null assertion operator !! converts any value to a non-null type and throws an exception if the value is null.

val nonNull = str!!.length

If you write str!!, it'll return a non-null value of str (str is a String? here) or throw an NPE if str is null. This operator should be used in cases where the developer is guaranteeing – the value will never be null. If you want an NPE, you have to ask for it explicitly.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • 5
    Asking as a beginner: why would I want to convert any value to a non-null type ? – Wolf359 May 13 '19 at 22:11
  • 11
    @Wolf359 It allows you to be 100% sure that its value is not null. ("it's common problem to debug an NPE and have a hard time locating the line / execution path that set the value to null. This null assignment could happen on a different context, class or even day!" by Cascader) – reducing activity Jul 12 '19 at 06:16
3

!!(Double Bang) operator is an operator to assert forcibly nullable variable as not null.

Example: Here str is a string with value. But its nullable. Since its nullable we need to handle null for avoid compile time exceptions.

  val str :String? = "Foo"
    val lowerCase = str!!.lowerCase()

    

Here if we add !! operator, since it has non null value it would work and lowercased value will be assigned.

val str :String? = "Foo"
str = null
val lowerCase = str!!.lowerCase() 

But here if you assign null value and use the particular value , it will throw KotlinNullPointerException.

One important thing here is, in most of the cases one should avoid as !! operator unless if its 100% sure that value is non null value or if the exception is caught and handled properly.

If you need to avoid this NPE, you can use null safe operators with elvis operators. null safe call ?. opertators with elvis are better way to handle null safety in kotlin. You can read more about Kotlin null safety here

Gowtham K K
  • 3,123
  • 1
  • 11
  • 29
2

!! is an assertion that it is not null. Two exclamation marks after a nullable value convert it to a non-nullable type. At the same time, before the conversion, it is not checked in any way that the value really does not contain null. Therefore, if during the execution of the program it turns out that the value that the !! operator is trying to convert is still null, then there will be only one way out - to throw a NullPointerException.

Vlad Tkachev
  • 107
  • 1
  • 8
0

Java

throws NullPointerException

Kotlin

simply use !!

This would help for understanding

GvSharma
  • 2,632
  • 1
  • 24
  • 30
0

It means in human language: I promise I will assign value later, but please don't worry for now my variable. On the other it is non-null variable terminologically.

Umut Atakul
  • 27
  • 1
  • 6