4 minute read

In Android, exceptions are categorized into checked and unchecked exceptions, just like in Java, since Android is built on the Java platform (or Kotlin, which compiles to Java bytecode). Here’s a breakdown:

1. **Checked Exceptions

In Kotlin, checked exceptions don’t exist in the same way as they do in Java. Kotlin doesn’t force you to catch or declare checked exceptions like IOException, SQLException, etc. This means that Kotlin simplifies exception handling by not requiring you to declare them in the function signature. However, you can still handle exceptions like Java.

Examples:

  • IOException: Thrown when there’s an I/O error (e.g., file read/write operations).
  • SQLException: Thrown when there’s an error in database operations.
  • ClassNotFoundException: Thrown when the JVM cannot find a specified class.

How to Handle Checked Exceptions in Kotlin:

Even though Kotlin doesn’t enforce checked exceptions, you can still handle them using try-catch.

Example:

fun readFile(filePath: String) {
	try {         
	val file = FileReader(filePath) // May throw IOException         
		val bufferedReader = BufferedReader(file) // File reading logic
	} catch (e: IOException) { // Handle IOException
		e.printStackTrace()     
	} 
}

You don’t need to declare IOException in the function signature because Kotlin allows unchecked exceptions for most cases, but you must catch them if needed.


2. Unchecked Exceptions in Kotlin

These exceptions are not checked at compile-time, so you don’t need to declare them or catch them. They usually occur due to bugs, invalid conditions, or programming mistakes (e.g., accessing an invalid index, performing a null operation, etc.).

Examples:

  • NullPointerException: Thrown when accessing or calling a method on a null object.
  • ArrayIndexOutOfBoundsException: Thrown when trying to access an invalid index in an array or list.
  • IllegalArgumentException: Thrown when a method is passed an illegal argument.
  • ArithmeticException: Thrown for mathematical errors like division by zero.

How to Handle Unchecked Exceptions in Kotlin:

Although you don’t have to explicitly handle unchecked exceptions, it’s best practice to prevent them by validating inputs and conditions before performing operations.

Example:

fun divideNumbers(num1: Int, num2: Int) {     
	try {         
		val result = num1 / num2 // May throw ArithmeticException if num2 is 0
		println(result)     
	} catch (e: ArithmeticException) {
	// Handle ArithmeticException (e.g., division by zero)         
	println("Error: Division by zero!")     
	} 
}

You can prevent NullPointerException by using Kotlin’s safe calls (?.) and elvis operator (?:) for null safety:

Example (Preventing NullPointerException):

fun printLength(str: String?) {     
	println(str?.length ?: "String is null") 
}

In this example, if str is null, it avoids throwing a NullPointerException and returns a default value.


Key Differences in Kotlin:

  1. Checked Exceptions: In Kotlin, there are no checked exceptions enforced by the compiler, unlike Java. However, you can still use try-catch to handle any potential errors like IOException or SQLException (even if not explicitly declared).

  2. Unchecked Exceptions: These exceptions (e.g., NullPointerException, ArithmeticException) are similar to Java’s unchecked exceptions. In Kotlin, you don’t have to declare them or handle them unless you want to prevent crashes or provide custom error handling.


Common Kotlin Example Scenarios:

  1. File I/O (Checked Exception): If you’re reading from a file, you might encounter an IOException. While Kotlin doesn’t force you to catch it, you can still do so using a try-catch block.
    fun readFile(filePath: String) {     
     try {         
         val file = FileReader(filePath)         
         val bufferedReader = BufferedReader(file)// File reading logic     
     } catch (e: IOException) {         
         e.printStackTrace() // Handle the error     
     } 
    }
    
  2. Null Pointer (Unchecked Exception): Kotlin has built-in null safety features to prevent NullPointerException. You can use safe calls (?.) or the !! operator (to force a NullPointerException if the object is null).
    fun printLength(str: String?) {     
     println(str?.length ?: "String is null") // Safe call with Elvis operator 
    }
    
  3. Array Index Out of Bounds (Unchecked Exception): Before accessing an array or list, always validate the index.
    fun accessArrayElement(arr: Array<Int>, index: Int) {     
     if (index in arr.indices) {         
         println(arr[index]) // Valid index access     
     } else {         
         println("Index out of bounds")     
     } 
    }
    

    Summary:

  • Checked Exceptions: In Kotlin, checked exceptions are not enforced (they don’t exist like in Java). However, you can still use try-catch blocks to handle them.
  • Unchecked Exceptions: These exceptions (like NullPointerException or ArithmeticException) occur at runtime. You don’t have to declare them, but it’s good practice to handle them by validating inputs and conditions before performing actions.

By leveraging Kotlin’s features like null safety and safe calls, you can significantly reduce the chances of encountering unchecked exceptions in your Android code.