Kotlin Exception Handling - try, catch, throw and finally
Exception handling is an important part of programming that helps us manage errors in our code without crashing the entire application. In this article, we will learn about exception handling in Kotlin, how to use try, catch, throw, and finally blocks, and understand different types of exceptions.
Kotlin Exceptions
An exception is an unexpected or unwanted event that occurs during the execution (run-time) of a program. It interrupts the normal flow of the program and can cause it to stop working if not handled properly. To prevent this, we use Exception Handling, a technique to catch errors, manage them gracefully, and keep the program running or shut it down safely with proper messages.
Types of Exceptions
In most programming languages, exceptions are divided into two types:
1. Checked Exceptions - These are exceptions checked at compile time. The compiler requires us to handle them using try-catch blocks or declare them using throws. Examples: IOException, FileNotFoundException
2. Unchecked Exceptions - These are exceptions that occur at run-time, often due to logical errors in the program. They are not checked at compile time. Examples: NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException
Note: In Kotlin, all exceptions are unchecked, meaning they are only detected at run-time. So we are not forced to handle them, but it's recommended to do so.
Throwing Exceptions in Kotlin
We can manually throw an exception using the throw keyword followed by an exception object.
throw Exception("Something went wrong")
In Kotlin, all exception classes are descendants of the Throwable class. Some of the common exceptions are:
- NullPointerException: It is thrown when we try to invoke a property or method on null object.
- Arithmetic Exception: It is thrown when invalid arithmetic operations are performed on numbers. eg - divide by zero.
- SecurityException: It is thrown to indicate security violation.
- ArrayIndexOutOfBoundException: It is thrown when we try to access invalid index value of an array.
Example -
fun main() {
val num = 10 / 0
println(num)
}
Output:
Exception in thread "main" java.lang.ArithmeticException: / by zero
In the above program, we initialize the num
variable with value 10/0, but we know in arithmetic divide by zero is not allowed. While we are trying to run the program it throws an exception. To solve this problem, we have to use try-catch block.
Handling Exceptions with try-catch
In Kotlin, we use try-catch block for exception handling in the program. The try block encloses the code which is responsible for throwing an exception and the catch block is used for handling the exception. This block must be written within the main or other methods. Try block should be followed by either catch block or finally block or both.
Syntax -
try {
// Code that might throw an exception
} catch (e: ExceptionType) {
// Code to handle the exception
}
Example:
fun main() {
try {
val num = 10 / 0
println(num)
} catch (e: ArithmeticException) {
println("Divide by zero is not allowed")
}
}
Output:
Divide by zero is not allowed
Explanation:
In the above program, we have used try-catch block. The num
variable which can throw exception is enclosed within the braces of try block because divide by zero not defined in arithmetic. The exception caught by the catch block and execute the println()
statement.
Using try-catch block as an expression
As we already know, expression always returns a value. We can use kotlin try-catch block as an expression in our program. The value returned by the expression will be either last expression of try block or last expression of catch block. If an exception occurs in the code, then catch block returns the value.
Example:
fun test(a: Int, b: Int): Int {
return try {
a / b
} catch (e: ArithmeticException) {
println(e)
println("Divide by zero not allowed")
0
}
}
fun main() {
println(test(10, 2))
println(test(10, 0))
}
Output:
5
java.lang.ArithmeticException: / by zero
Divide by zero not allowed
0
In the above code, we have used try-catch as an expression. Declare a function test on the top of program and it return a value using try-catch block. We have invoked the test
function from main method and passed the parameter values (10,2) The test function evaluate the arguments and return try value (10/2 = 5). But in next call, we assed (b=0) and this time exception is caught and returns expression of catch block.
Kotlin finally block
In Kotlin, finally block is always executes irrespective of whether an exception is handled or not by the catch block. So it is used to execute important code statement. We can also use finally block with try block and skip the catch block from there.
Syntax of finally block with try block:
try {
// Code that might throw an exception
} catch (e: ExceptionType) {
// Handle the exception
} finally {
// Always executed
}
Example:
fun main() {
try {
val arr = arrayOf(1, 2, 3, 4, 5)
println(arr[6])
} finally {
println("This block always executes")
}
}
Output:
This block always executes
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 6 out of bounds for length 5
Explanation:
In the above program, we have used try with finally block and skipped the catch block. Here, exception is not handled by catch block but executes the finally block.
Using try, catch, and finally Together
We can combine all three to fully manage and clean up after exceptions.
Example:
fun main() {
try {
val result = 10 / 0
} catch (e: ArithmeticException) {
println(e)
} finally {
println("This block always executes")
}
}
Output:
java.lang.ArithmeticException: / by zero
This block always executes
Kotlin throw keyword
In Kotlin, we use throw keyword to throw an explicit exception. It can also be used to throw a custom exception.
Example -
fun checkPassword(password: String) {
// check length of string
if (password.length < 6) {
throw ArithmeticException("Password is too short")
}
}
fun main() {
checkPassword("123")
}
Output:
Exception in thread "main" java.lang.ArithmeticException: Password is too short