Sobes.tech
Junior

Kaip teisingai tvarkyti išimtis Kotlin?

sobes.tech AI

Atsakymas iš AI

Kotlin'e klaidų apdorojimui naudojama try...catch...finally struktūra. Galite iškviesti funkcijas, pažymėtas kaip @Throws, norėdami sąveikauti su Java kodu.

fun readFile(path: String): String {
    return try {
        // Bandymas įvykdyti pavojingą kodą
        java.io.File(path).readText()
    } catch (e: java.io.IOException) {
        // Konkretios išimties apdorojimas
        println("Klaida skaitant failą: ${e.message}")
        "" // Grąžinti numatytąją reikšmę klaidos atveju
    } finally {
        // Blokas, kuris visada vykdomas, nepriklausomai nuo išimties
        println("Failo skaitymo bandymas baigtas")
    }
}

Galite naudoti kelis catch blokus skirtingų išimčių apdorojimui:

fun processData(data: String) {
    try {
        // Kodas, kuris gali sukelti NumberFormatException arba NullPointerException
        val number = data.toInt()
        println("Skaičius: $number")
    } catch (e: NumberFormatException) {
        println("Neleistinas skaičiaus formatas: ${e.message}")
    } catch (e: NullPointerException) {
        println("Gauti nulio duomenys: ${e.message}")
    }
}

Kotlin neturi checked išimčių kaip Java. Funkcijos gali deklaruoti, kad jos gali mesti išimtis naudodamos @Throws, tačiau tai nėra privaloma Kotlin kode.

Dėl atvejų, kai funkcija gali sėkmingai užbaigti arba su klaida, dažnai naudojami sealed klasės arba Result tipas (eksperimentinėse Kotlin versijose) vietoje išimčių, ypač asinchroniniame kode.

Pavyzdys su sealed klase:

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("Dalyba iš nulio")
        }
        Success(a / b)
    } catch (e: Throwable) {
        Error(e)
    }
}

// Naudojimas:
fun processDivision() {
    when (val divisionResult = safelyDivide(10, 0)) {
        is Success -> println("Rezultatas: ${divisionResult.value}")
        is Error -> println("Klaida: ${divisionResult.exception.message}")
    }
}

Svarbu gaudyti tik tas išimtis, kurias galite apdoroti. Nenaudokite tuščių catch blokų. Jei reikia, įrašykite išimties informaciją į žurnalą.

Taip pat galite išmesti išimtis aiškiai naudodami raktinį žodį throw:

fun requirePositive(number: Int) {
    if (number <= 0) {
        throw IllegalArgumentException("Skaičius turi būti teigiamas")
    }
}