Skip to content

Instantly share code, notes, and snippets.

@rahularity
Last active July 19, 2020 17:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rahularity/239b4f5b8d46589bb6032b8e73abcd25 to your computer and use it in GitHub Desktop.
Save rahularity/239b4f5b8d46589bb6032b8e73abcd25 to your computer and use it in GitHub Desktop.
Kotlin Null Safety

Kotlin Null Safety

Null Safety

A variable that doesn't refers to anything, refers to null. Null is a keyword to allow a variable refer to nothing or to check if it exists (comparison can be done with == or !=)

In Kotlin - A variable cannot actually be null unless it is declared to allow for null.

Null can be allowed by suffixing the type name with ?

Example:

     fun nullSafety( val a : String, val b : String? ){     // here b is allowed for null

     }

Let's see what calling to above function are allowed and what callings are not allowed

     nullSafety("a", "b")     // :white_check_mark: Allowed
     nullSafety("a", null)    // :white_check_mark: Allowed
     nullSafety(null, "b")    // :x: Not Allowed
     nullSafety(null, null)   // :x: Not Allowed
     nullSafety(a, b)         // :interrobang: is only allowed if the compiler can prove that a cannot possibly be null.

Inside of nullSafety, the compiler will not allow you to do anything with b that would result in an exception if b should happen to be null - so you can do a.length, but not b.length. However, once you're inside a conditional where you have checked that b is not null, you can do it:

    fun nullSafety( val a : String, val b : String? ){     
         
         println(b.length)        // :x: NOT ALLOWED

         if (b != null) {         
             println(b.length)    // :white_check_mark: ALLOWED AFTER CHECKING FOR NULL CONDITION
         }
    }

Safe Call Operator ( ?. )

x?.y evaluates x, and if it is not null, then it evaluates x.y (without reevaluating x).

Basically safe call operator evaluates a chain by checking for null values.

     x && x.y && x.y.z &&& x.y.z.p 

     :point_down: // this can be written by safe call operator as // :point_down:

     x?.y?.z?.p

Elvis operator ( ?: )

x ?: y evaluates x, which becomes the result of the expression unless it's null, in which case you'll get y instead (which ought to be of a non-nullable type). This is also known as the "Elvis operator". You can even use it to perform an early return in case of null:

     val z = x ?: return y

This will assign x to z if x is non-null, but if it is null, the entire function that contains this expression will stop and return y (this works because return is also an expression, and if it is evaluated, it evaluates its argument and then makes the containing function return the result).

Not-null assertion operator ( !! )

Sometimes we know that we have a value x that is not null, but compiler is not able to identify the logic, in that case we need to explicitly tell the compiler that it should not care about about the variable to have a null value.

!! operator is used for this purpose.

Example:

     val x: String? = javaFunctionThatYouKnowReturnsNonNull()
     val y: String = x!!      // here the compiler will object as it is not sure if x is not null as x is declared to have null values.

!! will raise a NullPointerException if the value actually is null.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment