Ce face throw
throw semnalează o eroare: creează un obiect excepție și oprește imediat funcția curentă. Excepția „urcă” prin funcțiile apelante până la primul try/catch care o prinde; dacă nu există, programul se oprește și afișează mesajul și locul erorii.
Excepții folosite des: IllegalArgumentException (argument greșit), IllegalStateException (obiectul nu e în starea potrivită), UnsupportedOperationException. Funcțiile require(), check() și error() le aruncă mai scurt. Poți crea propriile excepții extinzând Exception sau RuntimeException.
throw este o expresie de tip Nothing (tipul care nu are valori). De aceea poate apărea oriunde se așteaptă o valoare: după ?:, într-o ramură when sau ca un întreg corp de funcție.
Exemple
Exemplul 1: Validarea argumentelor
Funcția aruncă IllegalArgumentException pentru o cantitate greșită. Apelantul prinde excepția și afișează mesajul.
fun adaugaInCos(produs: String, cantitate: Int): String {
if (cantitate <= 0) {
throw IllegalArgumentException("cantitatea trebuie să fie pozitivă, nu $cantitate")
}
return "$cantitate x $produs adăugat"
}
fun main() {
println(adaugaInCos("mere", 3))
try {
println(adaugaInCos("pere", -1))
} catch (e: IllegalArgumentException) {
println("Eroare: ${e.message}")
}
}
Rezultat
3 x mere adăugat
Eroare: cantitatea trebuie să fie pozitivă, nu -1
Exemplul 2: Excepție proprie
StocInsuficient extinde Exception și păstrează date suplimentare (cât lipsește).
class StocInsuficient(val produs: String, val lipsa: Int) :
Exception("Stoc insuficient pentru $produs: lipsesc $lipsa bucăți")
val stoc = mutableMapOf("laptop" to 2, "mouse" to 10)
fun vinde(produs: String, bucati: Int) {
val disponibil = stoc.getValue(produs)
if (bucati > disponibil) throw StocInsuficient(produs, bucati - disponibil)
stoc[produs] = disponibil - bucati
println("Vândut: $bucati x $produs, rămân ${stoc[produs]}")
}
fun main() {
vinde("mouse", 4)
try {
vinde("laptop", 5)
} catch (e: StocInsuficient) {
println(e.message)
println("Comandă de reaprovizionare: ${e.lipsa} x ${e.produs}")
}
}
Rezultat
Vândut: 4 x mouse, rămân 6
Stoc insuficient pentru laptop: lipsesc 3 bucăți
Comandă de reaprovizionare: 3 x laptop
Exemplul 3: throw ca expresie
throw stă după ?: și într-o ramură when, pentru că are tipul Nothing.
val judete = mapOf("IS" to "Iași", "CJ" to "Cluj", "TM" to "Timiș")
fun numeJudet(cod: String): String =
judete[cod] ?: throw NoSuchElementException("cod de județ necunoscut: $cod")
fun tva(categorie: String): Int = when (categorie) {
"standard" -> 21
"alimente" -> 11
else -> throw IllegalArgumentException("categorie necunoscută: $categorie")
}
fun main() {
println(numeJudet("IS"))
println("TVA alimente: ${tva("alimente")}%")
for (cod in listOf("CJ", "XX")) {
try {
println(numeJudet(cod))
} catch (e: NoSuchElementException) {
println("Eroare: ${e.message}")
}
}
}
Rezultat
Iași
TVA alimente: 11%
Cluj
Eroare: cod de județ necunoscut: XX
Greșeli frecvente
throw Exception("...")pentru orice: tipul general face greu de prins doar eroarea care te interesează. Alege un tip specific sau creează-ți unul.- Uitarea lui
throw:IllegalArgumentException("mesaj")scris singur doar creează obiectul, fără să oprească nimic. - Aruncarea de excepții pentru situații obișnuite (un produs care lipsește dintr-o căutare): întoarce
nullsau un rezultat, iar excepțiile păstrează-le pentru erori reale.
Comenzi înrudite
try, catch și finally: try execută cod care poate eșua, catch prinde excepția și o tratează, finally rulează întotdeauna la final.null și null safety (?. ?: !!): null înseamnă „nicio valoare”. Kotlin separă tipurile care acceptă null (String?) și oferă ?., ?: și !! pentru ele.when: Alege o ramură după valoarea unei expresii sau după prima condiție adevărată; înlocuiește switch din alte limbaje.class: class declară o clasă: un tip nou care grupează date (proprietăți) și comportament (metode).