Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Kotlin Exception Handling and Control Flow

Tech 1

Exception Hierarchy

In Kotlin, all exceptions inherit from the Throwable class. Each exception contains a message, stack trace, and an optional cause.

Exceptions are thrown using the throw expression:

throw RuntimeException("Something went wrong")

Try-Catch Blocks

Exception handling uses try-catch-finally blocks:

try {
    performOperation()
} catch (error: SpecificException) {
    handleSpecificError(error)
} catch (error: GeneralException) {
    handleGeneralError(error)
} finally {
    cleanupResources()
}

Zero or more catch blocks are alowed. The finally block is optional, but at least one catch or finally block must be present.

Try as an Expression

The try construct can return a value:

val result = try {
    convertStringToNumber(input)
} catch (exception: NumberFormatException) {
    defaultValue
} finally {
    logCompletion()
}

The expression evaluates to the last expression in the try block or the last expression in any of the catch blocks. The finally block does not affect the result.

Unchecked Exceptions

Kotlin does not have checked exceptions. Consider this Java interface:

Appendable append(CharSequence sequence) throws IOException;

This would require handling IOException everywhere append is called, even when appending to a StringBuilder. Kotlin avoids this verbosity by not enforcing checked exceptions.

Nothing Type

Since throw is a expression, it can be used in contexts like the Elvis operator:

val name = user.username ?: throw IllegalStateException("Username is mandatory")

The throw expression has type Nothing, which represents unreachable code. Functions that never return should declare Nothing as their return type:

fun terminateProcess(reason: String): Nothing {
    throw ProcessException(reason)
}

val username = user.name ?: terminateProcess("Missing user name")
processUsername(username) // Compiler knows username is initialized

The nullable variant Nothing? has exactly one value: null. During type inference, when a variable is initialized with null and no other type information is avialable, the compiler infers Nothing?:

val emptyValue = null // Type: Nothing?
val nullList = listOf(null) // Type: List<Nothing?>

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.