Sobes.tech
Junior

Jak správně zpracovávat výjimky v Kotlinu?

sobes.tech AI

Odpověď od AI

V Kotlinu se zpracování výjimek používá konstrukce try...catch...finally. Můžete volat funkce označené @Throws pro interakci s Java kódem.

fun readFile(path: String): String {
    return try {
        // Pokus o vykonání nebezpečného kódu
        java.io.File(path).readText()
    } catch (e: java.io.IOException) {
        // Zpracování konkrétní výjimky
        println("Chyba při čtení souboru: ${e.message}")
        "" // Výchozí hodnota při chybě
    } finally {
        // Blok, který se vždy provede
        println("Čtení souboru dokončeno")
    }
}

Lze použít více bloků catch pro zpracování různých typů výjimek:

fun processData(data: String) {
    try {
        // Kód, který může vyvolat NumberFormatException nebo NullPointerException
        val number = data.toInt()
        println("Číslo: $number")
    } catch (e: NumberFormatException) {
        println("Neplatný formát čísla: ${e.message}")
    } catch (e: NullPointerException) {
        println("Obdržena nulová data: ${e.message}")
    }
}

Kotlin nemá checked výjimky jako Java. Funkce mohou deklarovat, že mohou vyvolat výjimky pomocí @Throws, ale není to povinné.

Pro případy, kdy funkce může skončit úspěchem nebo chybou, se často používají sealed třídy nebo typ Result (v experimentálních verzích Kotlinu), namísto výjimek, zejména v asynchronním kódu.

Příklad se sealed třídou:

sealed class Result<out T>
data class Success<out T>(val value: T) : Result<T>()
data class Error(val exception: Throwable) : Result<Nothing>()

fun safelyDivide(a: Int, b: Int): Result<Int> {
    return try {
        if (b == 0) {
            throw ArithmeticException("Dělení nulou")
        }
        Success(a / b)
    } catch (e: Throwable) {
        Error(e)
    }
}

// Použití:
fun processDivision() {
    when (val divisionResult = safelyDivide(10, 0)) {
        is Success -> println("Výsledek: ${divisionResult.value}")
        is Error -> println("Chyba: ${divisionResult.exception.message}")
    }
}

Je důležité zachytit pouze ty výjimky, které dokážete zpracovat. Vyhýbejte se prázdným blokům catch. Pokud je potřeba, zaznamenejte informaci o výjimce do logu.

Také můžete výjimky explicitně vyhodit pomocí klíčového slova throw:

fun requirePositive(number: Int) {
    if (number <= 0) {
        throw IllegalArgumentException("Číslo musí být kladné")
    }
}