throw în Kotlin

Excepții Kotlin 1.0

Aruncă o excepție: oprește execuția normală și transmite eroarea până la primul catch potrivit.

Sintaxă
throw IllegalArgumentException("mesaj")
class StocInsuficient(mesaj: String) : Exception(mesaj)
val x = valoare ?: throw IllegalStateException("lipsă")

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 null sau 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).