Kotlin

Kotlin for Beginners – Part 3: Exception Handling and Null Safety

Pinterest LinkedIn Tumblr

Congrats! on reaching the third post for learning Kotlin. Now lets look at two important topics Exception handling and Null Safety. So, lets start…

Kotlin – Exception Handling

In general terms, exception handling in programming is a technique that allows us to handle the runtime errors caused by exceptions. An exception is an unwanted event that interrupts program’s normal flow. Program execution gets terminated when an exception occurs.

In Kotlin, all exception classes are descendants of class Throwable. To throw an exception object, Kotlin uses throw expression:

throw FirstException("throws an exception")  

Four keywords used in exception handling are:

  • try : try block contains set of statements which might generate an exception. It should be followed by either catch or finally or both.
  • catch : catch block is used to catch the exception that is thrown from try block.
  • finally : finally block is mandatory executed whether exception is handled or not. So it is used to execute important code.
  • throw : throw keyword is used to throw an exception explicitly.

There are two kinds of exceptions in Java (Kotlin’s elder sister 🙂 ) : 

  • Checked exceptions
  • Unchecked exceptions

Thankfully! Kotlin doesn’t support Checked exceptions.

Unchecked exceptions in Kotlin

These are those exceptions that are thrown because of mistakes in your code. They are a direct or indirect subclass of the RuntimeException superclass. 

Examples of unchecked exceptions are following:

  • ArithmeticException: thrown when you divide by zero.
  • ArrayIndexOutOfBoundsException: thrown when an array has been accessed with an illegal index. 
  • SecurityException: thrown by the security manager to indicate a security violation.
  • NullPointerException: thrown when invoking a method or property on a null object.

Suppose if there is a method that might throw an unchecked exception, then the method might not contain any information about the exception thrown on its method declaration. 

try – catch

As the rule goes in Java programming, try – catch are like brother and sister. A try block encloses the code (which may throw an exception) and the catch block is used to handle the exception. This block must be written within the method only. Here, try block must be followed by either catch block or finally block or both.

Simple example:

fun main(args: Array<String>) {
    val a = 5
    val b = 0
    var c : Int
    try {
        c = a/b
    } catch (e : Exception){
        println("Handled exception")
    }
}

//Output:
Handled exception

multi – catch block

In Kotlin, multiple catch blocks are used when different exceptions in try block are generated because we are using different types of operation in try block.

Simple example:

fun main(args: Array<String>) {
    try{
        var num = 5/0
        println(num)
    }
    catch(e: NumberFormatException){
        println("Numberformat exception")
    }
    catch(e: ArrayIndexOutOfBoundsException){
        println("ArrayIndexOutOfBounds")
    }
    catch(e: Exception){
        println("Some Exception occurred")
    }

    println("Out of try-catch block")
}

//Output:
Some Exception occurred
Out of try-catch block

nested try-catch block

A nested try-catch block is used where one try-catch block is implemented into another try block.

Its requirement arises where a block of code generates an exception and within that block another code statements also generates another exception.

Simple example:

fun main(args: Array<String>) {
    try {
        val num = 200 / 2
        println(num)
        try {
            val num2 = 100 / 0
            println(num2)
        }
        catch(e: NumberFormatException){
            println("NumberFormat Exception")
        }
    }
    catch(e: ArithmeticException){
        println("ArithmeticException")
    }
}

//Output:
100
ArithmeticException

finally block

finally block is used to execute compulsory code statement  as such block which is executed always whether an exception is handled or not. 

Simple example:

fun main (args: Array<String>){  
    try {  
        val data = 100 / 2  
        println(data)  
    } catch (e: NullPointerException) {  
        println(e)  
    } finally {  
        println("finally block executes")  
    }  
    println("below code")  
}  

//Output:
50
finally block executes
below code

Also, its interesting to note that finally block is not executed if program exits.

throw keyword

This is used to throw an explicit or custom exception.

Simple example:

fun main(args: Array<String>) {
    print("Please enter your name: ")
    val name = readLine()
    try{
        if (name == "Animesh"){
            throw Exception("You don't have access")
        }
        else
        {
            println("Welcome! You have access")
        }
    }
    catch (e: Exception){
        println(e.message)
    }
}

//Output:
Please enter your name: Animesh
You don't have access

Kotlin – Null Safety

Okay! now, time has come to discuss about Null safety in Kotlin. It is a method to reduce and rather eliminate the risk of null reference from the code statements. Kotlin compiler throws NullPointerException immediately if any null argument is passed without executing any other statements.

Kotlin’s type system eliminates NullPointerException from the code. NullPointerException can only possible on following causes:

  • A forcefull call to throw NullPointerException();
  • Uninitialized this-operator which is available in a constructor passed and used somewhere.
  • Use of external Java code as Kotlin is Java interoperability.

nullable and non-nullable types

Kotlin differentiates between references which can hold null (nullable reference) and which cannot hold null. Generally, types of String are non-nullable. To make string which holds null value, we have to explicitly define them by putting a ? behind the String as: String?

Simple example:

nullable types

fun main(args: Array<String>){  
var str1: String? = "Hi! Android" // nullable variable 
str1 = null  
    print(str1)  
}  

//Output:
null

non-nullable types

val str: String = null // compile time error  
str = "hello" // compile time error Val cannot be reassign  
var str2: String = "Hi! Android "  
str2 = null // compile time error  

Compiler will give error if we assign a null value to a non-nullable string.

checking for null

fun main(args: Array<String>){  
var str: String? = "Hi! Android"     // nullable variable
var len = if(str!=null) str.length else -1  
println("str is : $str")  
println("length of str is : $len")  
  
str = null  
println("string is : $str")  
len = if(str!=null) str.length else -1  
println("length of b is : $len")  
} 

//Output:

str is : Hi! Android
length of str is : 11
string is : null
length of b is : -1

Smart cast

To use nullable types, optionally, we can use smart casts. Smart cast is a feature in which Kotlin compiler tracks conditions inside if expression. If compiler founds a variable of nullable type then the compiler will allow to access the variable.

Simple example:

When we accessing a nullable type of String without safe cast it will give compile time error.

var string: String? = "Hi"  
    print(string.length) // Compile error 
 
//using smart cast

fun main(args: Array<String>){  
var string: String? = "Hi"  
    if(string != null) { // smart cast  
print(string.length) // It works now!  
    }  
}  

//Output:
2

We can also use is or !is for checking the variable, so that the compiler tracks this information and internally cast the variable to target type. This is usually done inside the scope if is or !is returns true.

Simple example:

//use of is for smart cast
fun main(args: Array<String>){  
val obj: Any = "Hi! Android"  
    if(obj is String) {  
                // No Explicit Casting needed.  
println("String length is ${obj.length}")  
    }  
}

//Output:
String length is 11

//use of !is for smart cast
fun main(args: Array<String>){  
val obj: Any = "Hi! Android"  
    if(obj !is String) {  
println("obj is not string")  
  
    } else  
    // No Explicit Casting needed.  
println("String length is ${obj.length}")  
}  

//Output:
String length is 11

Unsafe and Safe Cast Operator

as: unsafe cast operator

When its not possible to cast variable and an expression is thrown, this is called as unsafe cast. The unsafe cast is performed by the infix operator as.

Simple example:

fun main(args: Array<String>){ 
    val str1: String = "Hi! Android"
    val str2: String = str1 as String      // Works 
    println(str1) 
}

//Output:
Hi! Android

as?: safe cast operator

Kotlin language provides a safe cast operator as? for safely casting to a type. It returns a null if casting is not possible and not throw a ClassCastException exception.

Simple example:

fun main(args: Array<String>){ 
  
    var str1: Any = "Hi! Android"
    val str2: String? = str1 as? String     // it will work
    str1 = 11
    // type casting not possible, hence returns null to str3 
    val str3: String? = str1 as? String     
    val str4: Int? = str1 as? Int          // it will work
    println(str2) 
    println(str3) 
    println(str4) 
} 

//Output:

Hi! Android
null
11

elvis (?:) operator

This operator is used to return the non null value even when the conditional expression is null. Also, It is used to check the null safety of values.

Simple example:

fun main(args: Array<String>){  
  
var str: String? = null  
var str2: String? = "Hi! Android"  
var len1:  Int = str ?.length ?: -1  
var len2:  Int = str2 ?.length ?:  -1  
  
println("Length of string 1 is ${len1}")  
println("Length of string 2 is ${len2}")  
}  

//Output:
Length of string 1 is -1
Length of string 2 is 11

For further reading, please visit Kotlin for Beginners – Part 4: Collections and related concepts

 

 

 

 

 

Passionate about Mobile App Development. Trained in Java, Android, IOS Development, Databases, MEAN Stack and SAP. Strong communication, interpersonal, logical and team-building skills with proficiency in grasping new concepts quickly and utilizing the same in a productive manner. Apart from technical skills, Motivator, YouTuber, and Yogi.