Sobes.tech
Junior

Hogyan kezeljük helyesen a kivételeket Kotlinben?

sobes.tech MI

Válasz az MI-től

Kotlinben az exception kezelés a try...catch...finally szerkezet segítségével történik. Olyan függvényeket is hívhatunk, melyeket @Throws jelöléssel láttak el, hogy Java-kóddal való együttműködést biztosítsunk.

fun readFile(path: String): String {
    return try {
        // Kockázatos kód végrehajtása
        java.io.File(path).readText()
    } catch (e: java.io.IOException) {
        // Egy adott kivétel kezelése
        println("Hiba a fájl olvasásakor: ${e.message}")
        "" // Alapértelmezett érték hiba esetén
    } finally {
        // Mindig végrehajtódó blokk
        println("Fájl olvasás befejeződött")
    }
}

Több catch blokk is használható különböző kivételek kezelésére:

fun processData(data: String) {
    try {
        // Kód, ami NumberFormatException vagy NullPointerException-t okozhat
        val number = data.toInt()
        println("Szám: $number")
    } catch (e: NumberFormatException) {
        println("Érvénytelen számformátum: ${e.message}")
    } catch (e: NullPointerException) {
        println("Null adatokat kaptunk: ${e.message}")
    }
}

Kotlinben nincsenek checked kivételek, mint Java-ban. A függvények deklarálhatják, hogy kivételeket dobhatnak, @Throws használatával, de ez nem kötelező.

Olyan esetekben, amikor egy függvény sikerrel vagy hibával fejeződik be, gyakran használnak sealed-klasseket vagy a Kotlin kísérleti verzióiban a Result típust, a kivételek helyett, különösen aszinkron kódban.

Példa sealed-klasse-re:

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("Nullával való osztás")
        }
        Success(a / b)
    } catch (e: Throwable) {
        Error(e)
    }
}

// Használat:
fun processDivision() {
    when (val divisionResult = safelyDivide(10, 0)) {
        is Success -> println("Eredmény: ${divisionResult.value}")
        is Error -> println("Hiba: ${divisionResult.exception.message}")
    }
}

Fontos, hogy csak azokat a kivételeket fogd el, amelyeket kezelni tudsz. Kerüld az üres catch blokkokat. Szükség esetén logolhatod az exception-t.

A throw kulcsszóval explicit módon is dobhatod az exception-t:

fun requirePositive(number: Int) {
    if (number <= 0) {
        throw IllegalArgumentException("A szám pozitív kell legyen")
    }
}