Kotlin Exception Handling finally Block Tutorial

In this section, we will learn what the finally block is and how to use it in Kotlin.

Note: we’re assuming you’re familiar with the exception handling in Kotlin.

What is finally keyword in Kotlin?

When an exception is thrown in a program, we mentioned that our program jumps out of the normal flow of the instruction execution and starts to handle the exception by looking for the closest catch block that relates to the thrown exception in order to invoke and run it.

This break of normal flow might become dangerous for your program if there are some critical instructions that must be executed no-matter if an exception occurred or not!

For example, let’s say the purpose of the program is to open a connection to a file or a database in order to read and update part of that external resource! Now, when opening a connection between a database or a file, it’s important to close that resource after the work of the program is done!

But let’s say an exception was just thrown right after the connection opened and a little data came from that external resource.

So here our instructions to close the connection is in danger! Basically, there’s a good chance that this closing instruction might never get a chance to run!

So what should we do? What’s one thing that will guarantee the execution of critical codes no-matter if an exception is thrown or not?!

Well, the answer is the finally clause!

The finally clause (or finally block) is a block that can be added to a try clause right after the catch clauses of the target try clause and Kotlin guarantees that any instructions we put in this finally block will be executed no-matter if an exception happens or not!

Alright, before we continue our discussion related to the work of the finally block, first let’s look at the syntax of this block and see how we can add a finally block to a try statement.

Kotlin finally block syntax:

This is the syntax of using the finally block:

try{

}catch(param:ExceptionType){

}finally{

}

As you can see, the finally block comes after all the handler of the target try block and it doesn’t have any condition like the way the catch clause does.

Simply put, a pair of curly braces to define the body of the finally block and then write any code you want to be executed after work of the try block (Doesn’t matter if an exception is thrown or not, the finally block will always execute at the end).

Example: using finally block in Kotlin

fun main(){
    
    try{
        division(100, 0)
        println("After calling the function in the try block")
    }catch(obj:ArithmeticException){
        println("This is the message of the thrown exception: ")
        println(obj.message)
    }finally{
        println("This message is coming from the finally block of the try-catch")
    }

    println("The message after the try-catch clauses")
}

fun division(val1:Int, val2:Int):Int{

    return val1/val2
}

Output:

This is the message of the thrown exception:

/ by zero

This message is coming from the finally block of the try-catch

The message after the try-catch clauses

Note that here we’ve called the division function and got an exception as a result. Then the catch block of the try statement ran and handled the thrown exception.

Now instead of moving to the rest of the program after the try-catch block, our program first runs the finally block and then proceeds to the rest of the program that comes after the finally block.

Using Kotlin finally block without a catch block

When a try block has a finally block attached to it, the use of catch block becomes optional! That means we can have one try clause and right after that set a finally block without any catch block in between.

For example:

try{

//Instructions…

}finally{

//Instructions…

}

Example: Kotlin finally block without a catch block

fun main(){
    
    try{
        division(100, 0)
        println("After calling the function in the try block")
    }finally{
        println("The exception is unhandled but the body of the finally block still runs! ")
    }

    println("The message after the try-catch clauses")
}

fun division(val1:Int, val2:Int):Int{

    return val1/val2
}

Output:

The exception is unhandled but the body of the finally block still runs!

Exception in thread "main" java.lang.ArithmeticException: / by zero

Here you can see that the try statement doesn’t come with a catch block, so the thrown exception won’t be handled! But even there, before our program crashes, Kotlin first runs the finally block and all the instructions in that block and then proceeds to send the details of the exception to the output stream and stop the program afterward.

Note: as you can see, the last statement within the body of the main function (that println() call) didn’t run because of this unhandled exception.

Cases where finally block executes in Kotlin:

Now that we are familiar with the finally block, let’s go and run the stages that finally block will run.

For example, when an exception is thrown, we now know that the finally block will run as well. Even if no exception is thrown, still the finally block will run.

But there are other settle cases that you might think this block won’t run in those situations! So now let’s see them and run programs to see how the finally block would react in those delicate situations!

1- No Exception is thrown

The first case that the finally block will run is when you have a try block and no exception is thrown there!

In such case, if the try block has catch clause as well, it’ll be skipped, but the finally block will run after the instructions within the body of the try block ended.

Basically, the control flow moves from the try block to the finally block.

Example: no-exception and finally block in Kotlin

fun main(){
    
    try {
        println("Before calling the dontThrowException method")
        println(dontThrowException())
        println("After calling the dontThrowException method")
    }catch (e:Exception){
        println(e.message)
    }

    println("The message after the try-catch clauses")
}

fun dontThrowException():String{
    try{
        println("The body of the try block in the dontThrowException method")
        return "This message is coming from the try block"
    }finally {
        println("The body of the finally block in the dontThrowException method")
    }
}

Output:

Before calling the dontThrowException method

The body of the try block in the dontThrowException method

The body of the finally block in the dontThrowException method

This message is coming from the try block

After calling the dontThrowException method

The message after the try-catch clauses

2- Exception is thrown but not handled

Let’s say an exception is thrown and none of the catch clauses of the target try block could handle the exception! Basically, it’s the case where your program might crash! But before that happens, it is guaranteed that the finally block of the try block will run in this situation! So any critical code can go into the body of the finally block with the assurance that they will run even if there’s an unhandled exception.

Example: Kotlin finally block and not handled exception

fun main(){
    
    try {
        println("Before calling the throwException method")
        throwException()
        println("After calling the throwException method")
    }catch (e:Exception){
        println(e.message)
    }

    println("The message after the try-catch clauses")
}

fun throwException(){
    try{
        println("The body of the try block in the throwException method")
        throw Exception("This is an unhandled exception")
    }finally {
        println("The body of the finally block in the throwException method")
    }
}

Output:

Before calling the throwException method

The body of the try block in the throwException method

The body of the finally block in the throwException method

This is an unhandled exception

The message after the try-catch clauses

Here within the body of the throwException function, we have one unhandled exception that is created using the Exception class (It inherits from the Throwable class) and we used the throw statement to throw this handmade exception.

Now before our program terminates this function and gets back to the main function, we can see that the body of the finally block ran!

3- Exception is thrown and handled perfectly

Another case where the finally block will run is when an exception is thrown, but one of the catch clauses of the target try block handled the exception properly! So now the control flow of the program moves out of the catch block that handled the exception and jumps into the related finally block to run the instructions from there.

Example: Kotlin finally block and handled exception

fun main(){
    
    try {
        println("Before calling the throwException method")
        throwException()
        println("After calling the throwException method")
    }catch (e:Exception){
        println(e.message)
    }

    println("The message after the try-catch clauses")
}

fun throwException(){
    try{
        println("The body of the try block in the throwException method")
        throw Exception("This is an unhandled exception")
    }catch(e:Exception){
    	println("The body of the catch block in the throwException method, the message of the thrown exception is: ")
    	println(e.message)
    }finally {
        println("The body of the finally block in the throwException method")
    }
}

Output:

Before calling the throwException method

The body of the try block in the throwException method

The body of the catch block in the throwException method, the message of the thrown exception is:

This is an unhandled exception

The body of the finally block in the throwException method

After calling the throwException method

The message after the try-catch clauses

4- Function returns from a try or catch block

This is a case where we have a call to the return statement in the body of either a try block or one of its catch clauses. We know that when a call to the return statement happens, the work of the function is done and it should return to the caller of that function. But if there’s a finally block in that function, it will run first, before the call to the return statement can happen! After the execution of the finally block, the target suspended return statement will continue to run.

Example: Kotlin finally block and the return statement in try or catch block

fun main(){
    
    try {
        println("Before calling the dontThrowException method")
        println(dontThrowException())
        println("After calling the dontThrowException method")
    }catch (e:Exception){
        println(e.message)
    }

    println("The message after the try-catch clauses")
}

fun dontThrowException():String{
    try{
        println("The body of the try block in the dontThrowException method")
        return "returning from the dontThrowException function"
    }catch(e:Exception){
    	println("The body of the catch block in the dontThrowException method, the message of the thrown exception is: ")
    	println(e.message)
    }finally {
        println("The body of the finally block in the dontThrowException method")
    }
    return " "
}

Output:

Before calling the dontThrowException method

The body of the try block in the dontThrowException method

The body of the finally block in the dontThrowException method

returning from the dontThrowException function

After calling the dontThrowException method

The message after the try-catch clauses

Using return statement in Kotlin finally block

Note that if there’s a call to the return statement in the body of either try block or one of its catch clause and we also have a return statement in the related finally block, the result of the return statement in the finally statement is the one that will be used as the final value of the target function!

Basically, the other return statements in the other blocks will be skipped.

Example: return statement in Kotlin finally block

fun main(){
    
    try {
        println("Before calling the dontThrowException method")
        println(dontThrowException())
        println("After calling the dontThrowException method")
    }catch (e:Exception){
        println(e.message)
    }

    println("The message after the try-catch clauses")
}

fun dontThrowException():String{
    try{
        return "This message is coming from the try block";
    }finally {
        return "This message is coming from the finally block";
    }
    return " "
}

Output:

Before calling the dontThrowException method

This message is coming from the finally block

After calling the dontThrowException method

The message after the try-catch clauses

Here the value of the return statement in the finally block of the dontThrowException function returned as the final value of this function.

Facebook
Twitter
Pinterest
LinkedIn

Top Technologies