Sobes.tech
Junior

Cum se gestionează corect excepțiile în Kotlin?

sobes.tech AI

Răspuns de la AI

În Kotlin, gestionarea excepțiilor se face folosind construcția try...catch...finally. Poți apela funcții marcate cu @Throws pentru a interacționa cu cod Java.

fun readFile(path: String): String {
    return try {
        // Încercare de a executa cod periculos
        java.io.File(path).readText()
    } catch (e: java.io.IOException) {
        // Tratarea unei excepții specifice
        println("Eroare la citirea fișierului: ${e.message}")
        "" // Valoare implicită în caz de eroare
    } finally {
        // Bloc care se execută întotdeauna, indiferent de excepție
        println("Citirea fișierului s-a încheiat")
    }
}

Se pot folosi mai multe blocuri catch pentru a trata diferite tipuri de excepții:

fun processData(data: String) {
    try {
        // Cod care poate arunca NumberFormatException sau NullPointerException
        val number = data.toInt()
        println("Număr: $number")
    } catch (e: NumberFormatException) {
        println("Format de număr invalid: ${e.message}")
    } catch (e: NullPointerException) {
        println("Date nule primite: ${e.message}")
    }
}

Kotlin nu are excepții verificate ca în Java. Funcțiile pot declara că pot arunca excepții folosind @Throws, dar acest lucru nu este obligatoriu.

Pentru cazurile în care o funcție poate avea succes sau eșua, se folosesc adesea clase sealed sau tipul Result (în versiunile experimentale de Kotlin), în loc de excepții, mai ales în codul asincron.

Exemplu cu clasă sealed:

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("Împărțire la zero")
        }
        Success(a / b)
    } catch (e: Throwable) {
        Error(e)
    }
}

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

Este important să capturați doar acele excepții pe care le puteți trata. Evitați blocurile catch goale. Dacă este necesar, înregistrați informațiile despre excepție în jurnal.

De asemenea, puteți arunca excepții explicit folosind cuvântul cheie throw:

fun requirePositive(number: Int) {
    if (number <= 0) {
        throw IllegalArgumentException("Numărul trebuie să fie pozitiv")
    }
}