Ce face try, catch și finally
Când o operație eșuează (un text care nu e număr, un fișier care lipsește, o împărțire la zero), programul aruncă o excepție. Dacă nimeni nu o prinde, programul se oprește. Codul care poate eșua se pune în try { }, iar după el, unul sau mai multe blocuri catch (e: TipExceptie) { } care tratează eroarea. Se alege primul catch al cărui tip se potrivește, deci tipurile specifice se scriu înaintea celor generale (Exception).
finally { } se execută întotdeauna: după try reușit, după un catch și chiar dacă se iese cu return. Acolo se pun operațiile de curățenie, de exemplu închiderea unei conexiuni. Pentru fișiere, use { } face acest lucru automat.
În Kotlin try este o expresie: val n = try { text.toInt() } catch (e: NumberFormatException) { 0 }. Kotlin nu are excepții verificate („checked”): nu ești obligat să prinzi sau să declari excepțiile, ca în Java.
Ce returnează
Folosit ca expresie: ultima valoare din try sau din catch-ul executat (nu din finally).
Exemple
Exemplul 1: Text care nu este număr
toInt() aruncă NumberFormatException pentru „doi”. Excepția este prinsă și programul continuă.
fun main() {
for (text in listOf("3", "doi", "5")) {
try {
val bucati = text.toInt()
println("Comand $bucati pizza, total ${bucati * 35} lei")
} catch (e: NumberFormatException) {
println("'$text' nu este număr: ${e.message}")
}
}
println("Programul a continuat")
}
Rezultat
Comand 3 pizza, total 105 lei
'doi' nu este număr: For input string: "doi"
Comand 5 pizza, total 175 lei
Programul a continuat
Exemplul 2: try ca expresie și mai multe catch
Primul catch potrivit este ales. Valoarea lui try este pusă direct în variabilă.
fun pretPePersoana(total: String, persoane: Int): String =
try {
val suma = total.toInt()
"${suma / persoane} lei de persoană"
} catch (e: NumberFormatException) {
"total invalid"
} catch (e: ArithmeticException) {
"împărțire la zero: ${e.message}"
}
fun main() {
println(pretPePersoana("240", 4))
println(pretPePersoana("2x0", 4))
println(pretPePersoana("240", 0))
}
Rezultat
60 lei de persoană
total invalid
împărțire la zero: / by zero
Exemplul 3: finally se execută mereu
Mesajul din finally apare în toate cele trei cazuri: reușită, eroare prinsă și return din try.
fun proceseaza(comanda: String): String {
println("Deschid conexiunea pentru '$comanda'")
try {
if (comanda.isEmpty()) return "comandă goală"
val cod = comanda.toInt()
return "comanda $cod salvată"
} catch (e: NumberFormatException) {
return "cod invalid"
} finally {
println("Închid conexiunea")
}
}
fun main() {
println(proceseaza("1024"))
println(proceseaza("abc"))
println(proceseaza(""))
}
Rezultat
Deschid conexiunea pentru '1024'
Închid conexiunea
comanda 1024 salvată
Deschid conexiunea pentru 'abc'
Închid conexiunea
cod invalid
Deschid conexiunea pentru ''
Închid conexiunea
comandă goală
Greșeli frecvente
catch (e: Exception)pus primul: prinde tot, iarcatch-urile specifice de după nu mai ajung să ruleze niciodată.- Un
catchgol, care ascunde eroarea: programul continuă cu date greșite și problema e greu de găsit. Măcar afișează sau înregistrează mesajul. - Folosirea excepțiilor pentru cazuri normale: pentru texte care pot să nu fie numere,
toIntOrNull()este mai simplu decâttry/catch.
Comenzi înrudite
throw: Aruncă o excepție: oprește execuția normală și transmite eroarea până la primul catch potrivit.null și null safety (?. ?: !!): null înseamnă „nicio valoare”. Kotlin separă tipurile care acceptă null (String?) și oferă ?., ?: și !! pentru ele.return: Încheie funcția curentă și întoarce o valoare apelantului; cu etichetă (return@forEach) iese doar din lambda.