Exceptions

    To throw an exception object, use the throw-expression:

    To catch an exception, use the try-expression:

    1. try {
    2. // some code
    3. }
    4. // handler
    5. }
    6. finally {
    7. // optional finally block
    8. }

    There may be zero or more catch blocks. finally block may be omitted. However at least one catch or finally block should be present.

    try is an expression, i.e. it may have a return value:

    1. val a: Int? = try { parseInt(input) } catch (e: NumberFormatException) { null }

    The returned value of a try-expression is either the last expression in the try block or the last expression in the catch block (or blocks). Contents of the finally block do not affect the result of the expression.

    The following is an example interface of the JDK implemented by StringBuilder class:

    What does this signature say? It says that every time I append a string to something (a , some kind of a log, a console, etc.) I have to catch those IOExceptions. Why? Because it might be performing IO (Writer also implements Appendable)… So it results in this kind of code all over the place:

    1. try {
    2. log.append(message)
    3. catch (IOException e) {
    4. // Must be safe
    5. }

    And this is no good, see Effective Java, 3rd Edition, Item 77: Don’t ignore exceptions.

    Bruce Eckel says about checked exceptions:

    If you want to alert callers of possible exceptions when calling Kotlin code from Java, Swift, or Objective-C, you can use the @Throws annotation. Read more about using this annotation as well as for Swift and Objective-C.

    throw is an expression in Kotlin, so you can use it, for example, as part of an Elvis expression:

    The type of the throw expression is the special type Nothing. The type has no values and is used to mark code locations that can never be reached. In your own code, you can use Nothing to mark a function that never returns:

    When you call this function, the compiler will know that the execution doesn’t continue beyond the call:

    1. val s = person.name ?: fail("Name required")
    2. println(s) // 's' is known to be initialized at this point

    Another case where you may encounter this type is type inference. The nullable variant of this type, Nothing?, has exactly one possible value, which is null. If you use null to initialize a value of an inferred type and there’s no other information that can be used to determine a more specific type, the compiler will infer the Nothing? type:

    1. val l = listOf(null) // 'l' has type `List<Nothing?>