Nullability in Kotlin

Nullability is the ability of a data type to become null during the execution time and throw NullPointer Exception to stop/crash the application

Kotlin converts these Nullable problems from runtime into compile time so that user would be able to see the null error during the compile time. So this will avoid the null pointer exception during the execution/run time

What are Non-Nullable DataTypes in kotlin ?

Non-Nullable data types are nothing but normal data types, that we use in day to day life. These data types will never accept a null as a value
Eg : String, Int, Float...

What is Nullable dataType in kotlin ?

Nullable data types are also the same as Normal datatypes but these will accept the null values as well. We have to add question mar at the end of the datatype to make it as Nullable.
EG: String?, Int?, Float?...

How kotlin Avoids NullPointerException :

  • Normal data types don't allow you to store the null
    not-nullable-string
  • Kotlin doesn't allow the function calls on a nullable variable because allowing function calls on a variable which possibly hold a null value, you find it in below example
  • If we create a function with non-nullable type, then no matter what Kotlin will not allow passing a null value to that method. Kotlin compiler finds the null value while passing the parameter and shows error
    cannot-accept-null-kotlin-function
  • If you create a function with nullable type then without checking for null, you cannot access the methods
    nullable-function-parameter-kotlin
  • Corrected above code
    null-check-in-if-block-kotlin-function
    Reasons for NullPointerException in Kotlin :
  • When you call the NullPointerException explicitly to throw an exception
  • When we use !! (double not) operator
  • When the program has External java code

Ways to checking for Null Types :

  • Checking with Safe Call Operator ?.
  • Elvis Operator ?:
  • Safe casts as?
  • Double not Operator !!

Kotlin Poses some restriction on function if they accept Nullable Parameter if you don't compare the value with null:

  • You cannot call methods on the parameter you receive whether it is null or not
  • You cannot assign this variable to any other non-nullable data type inside the method
  • You cannot pass this value to any other method which accepts non-nullable parameters
How to avoid problems when you use Nullable parameters in a function :
  • Compare to check whether the received value is null or not and perform an operation according to it
  • The compiler remember that value is not null as a result of the above step through the block only, so use it accordingly

Any & Unit & nothing

Safe Call Operator [?.] in kotlin

You might not be able to use if and else everywhere to check whether a value null or not and then to use the value, as shown in the last topic.

So, What is Safe Call Operator [?.] in Kotlin ?
Safe call operator is represented by ?. and safe call operator helps the user to perform a null check and then call a method or call to property(aka variable).

safe-call-operator-kotlin

Safe call operator calls the method / property only if the given object is not null, if the object is null then safe call operator will not give a call to the method or variable(property).

fun main(args:Array<String>)
{
    lengthOfStringNormalMethod("I have never watched star-wars")
    lengthOfStringSafeCall("star-trek as well")
}
// using if block t check null
fun lengthOfStringNormalMethod(str:String?){
    if(str != null){
        // calling function
        println(str.toUpperCase())
        // below is calling variable
        println(str.length)
    }else{
        println("It is a null value")
    }
}
// using safe call operator
fun lengthOfStringSafeCall(str:String?){
    // calling function
    println(str?.toUpperCase())
    // below is calling variable
    println(str?.length)
}

Operators in Kotlin

Elvis Operator [?:] in Kotlin

We have to use safe call operator every time whenever we call a method or variable on a nullable variable, the code becomes tedious and lengthy.

What is Elvis Operator in Kotlin ?
Elvis operator is performed on the nullable object to check whether a given value is null or not, if it is null then Elvis operator will replace the value with a given default value.

elvis-operator-kotlin

Elvis operator may almost like a ternary operator in other languages.

fun main(args:Array<String>)
{
    lengthOfStringElvisOperator("I liked Thanos than Avengers")
    println("******Calling with null******")
    lengthOfStringElvisOperator(null)
}
// using Elvis operator
fun lengthOfStringElvisOperator(str:String?)
{
    var elvisString:String = str ?: "I am default value, buddy"
    println(elvisString)
}

Elvis operator and Safe call Operator :

If an Object is null we can use the Elvis Operator to replace the null, value with some default value but if we are trying to access a method and use that value in Elvis then we have to use Safe call Operator.

In simple terms, Previously we have checked whether given Object is null but what if Object is not null but the method we access inside the object returns null, so in this case, we have to use Safe Operator along with Elvis Operator

fun main(args:Array<String>)
{
    var se = SampleExample()
    // using safe call and elvis
    var yeahString = se?.i_Return_Value() ?: "I am default"
    println(yeahString)
    println("****Below Method returns null*****")
    // using safe call and elvis
    var nullString = se?.i_Return_Null() ?: "I am default"
    println(nullString)
}
class SampleExample
{
    fun i_Return_Value():String {
        return "I am a String Value"
    }
    fun i_Return_Null():String? {
        return null
    }
}

In Above kotlin Program, I have used this below line of code, and let's write that in Java

var nullString = se?.i_Return_Null() ?: "I am default"

In java

var nullString:String;
if(se==null)
{
    nullString = "I am default"
}else if(se.i_Return_Null() == null)
{
    nullString = "I am default"
}else
{
    nullString = se.i_Return_Null();
}

Static functions in Kotlin

Smart cast Operator [as?] in Kotlin

As I explained earlier, casting is nothing but changing the one type of object onto other types. Most of the time smart cast operator is used to convert the one type to other in kotlin.

When Smart cast operator [as] fails to convert one type to another type then it throws ClassCastExceptionin kotlin, so this is also one of the places we may see the exception on run time.

Below Example, tries to convert the string into Int, which not possible as the string contains Alphabets only, so the conversion will throw class cast exception.

fun main(args:Array<String>)
{
    var abc:Any="ppp"
    // casting into Int
    var intAbc:Int? = abc as Int
    println(intAbc)
}

During these time we would be using Nullable Smart Cast operator [as?] to return null if the casting type exception occurs.

as-safe-smart-cast-operator-kotlin

Below example tries to convert the "ppp" string into int value but it throws Class cast exception, but we are using smart cast with safe class [as?], so instead of Exception, we may receive the value as null.

fun main(args:Array<String>)
{
    var abc:Any="ppp"
    // casting into Int
    var intAbc:Int? = abc as? Int
    println(intAbc)
}

Elvis Operator with Smart Cast Operator :

In the above example, the program provides null as value as the casting result, what can I do with null value as Int type, Literally Nothing.

So to avoid this null value we have to provide some default value when null value occurs in Casting, for that purpose we can use Elvis Operator in kotlin to provide some default value when a value is null.

fun main(args:Array<String>)
{
    var abc:Any="ppp"
    // casting into Int
    var intAbc:Int? = abc as? Int
    println(intAbc)
    // casting into Int with Elvis to avoid null
    var intAbcElvis:Int? = abc as? Int ?: 0
    println(intAbcElvis)
}

But above Elvis code looks little confusing let me re-write that line, I recommend you write like this only. Put parentheses around the expression which will be going to null.

var intAbcElvis:Int? = (abc as? Int) ?: 0

Kotlin Standard Functions

Not Null Assertion [!!] Operator (Double Exclamation Mark Operator)

What is Not Null Assertion [!!] in Kotlin ?
Not Null Assertion operator in kotlin converts the objects of the Nullable types into Non-Nullable data type object in kotlin to access method and variable from the object

Kotlin restricts the user to use the methods or variables on the Nullable data types to avoid the NullPointerException as the Nullable types can also hold the value null.

In below code, you might face exception like below, it happens because kotlin doesn't allow you access methods/variable when you are using Nullable types.

This error may happen while running below code in this browser as this browser is not Integrated with Compiler but when you same code in any IDE, you might see the error on compile-time itself.

Error:(14, 22) Kotlin: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
fun main(args:Array<String>)
{
    var abc:String?="ppp"
    var stringAbc = abc
    println(stringAbc.length)
}

Let's convert the Nullable type into Non-Nullable type in kotlin and then try to call the method.

fun main(args:Array<String>)
{
    var abc:String?="ppp"
    // convert using the Not Null assertion
    var stringAbc = abc!!
    println(stringAbc.length)
}

While using Not-Null operator you must be sure that you are not converting the null value, if you so you might face below error

Exception in thread "main" kotlin.KotlinNullPointerException
fun main(args:Array<String>)
{
    var abc:String? = null
    var newString = abc!!
    // trying to print the length
    print(newString.length)
}                                                                                                     

Lambda in Kotlin

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions