Ce face require
require(conditie) { "mesaj" } se pune la începutul unei funcții pentru a verifica argumentele primite. Dacă condiția este falsă, aruncă IllegalArgumentException cu mesajul din bloc. Blocul cu mesajul rulează doar la eroare, deci nu costă nimic când totul e în regulă.
requireNotNull(valoare) { "mesaj" } verifică dacă valoarea nu este null și o returnează cu tipul fără ?. După apel, compilatorul știe că valoarea există (smart cast).
Regula: require pentru greșeli ale celui care apelează funcția (argumente), check pentru starea obiectului, error pentru situații imposibile.
Parametri
| Parametru | Descriere |
|---|---|
value |
Condiția care trebuie să fie adevărată (la require) sau valoarea care nu trebuie să fie null (la requireNotNull). |
lazyMessage: () -> Any |
Bloc care produce mesajul excepției; rulează doar dacă verificarea eșuează. Fără el, mesajul este „Failed requirement.”. |
Ce returnează
require: nimic. requireNotNull: valoarea, cu tip non-null. Ambele aruncă IllegalArgumentException la eșec.
Exemple
Exemplul 1: Verificarea argumentelor unei funcții
Al doilea și al treilea apel nu trec de require; excepția este prinsă și i se afișează mesajul.
fun retrage(sold: Double, suma: Double): Double {
require(suma > 0) { "Suma trebuie să fie pozitivă, nu $suma" }
require(suma <= sold) { "Fonduri insuficiente: sold $sold lei, ceri $suma lei" }
return sold - suma
}
fun main() {
println("Sold nou: ${retrage(500.0, 120.0)} lei")
for (suma in listOf(-10.0, 900.0)) {
try {
retrage(500.0, suma)
} catch (e: IllegalArgumentException) {
println("Eroare: ${e.message}")
}
}
}
Rezultat
Sold nou: 380.0 lei
Eroare: Suma trebuie să fie pozitivă, nu -10.0
Eroare: Fonduri insuficiente: sold 500.0 lei, ceri 900.0 lei
Exemplul 2: requireNotNull și mesajul implicit
După requireNotNull, oras are tipul String, deci length se folosește fără ?.. Fără bloc de mesaj, require dă „Failed requirement.”.
fun lungimeOras(date: Map<String, String>): Int {
val oras = requireNotNull(date["oras"]) { "Lipsește câmpul „oras”" }
return oras.length
}
fun main() {
println(lungimeOras(mapOf("oras" to "Constanța")))
try {
lungimeOras(mapOf("nume" to "Ana"))
} catch (e: IllegalArgumentException) {
println(e.message)
}
try {
val note = listOf(4, 3)
require(note.all { it >= 5 })
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
Rezultat
9
Lipsește câmpul „oras”
Failed requirement.
Greșeli frecvente
- Folosești require pentru starea obiectului (de exemplu „conexiunea e deschisă”). Excepția corectă acolo este
IllegalStateException, dată decheck. - Construiești mesajul ca text normal:
require(x > 0, "mesaj")nu compilează. Mesajul se dă într-un bloc:require(x > 0) { "mesaj" }.
Comenzi înrudite
check: Verifică starea programului și aruncă IllegalStateException dacă nu este cea așteptată; checkNotNull cere o valoare diferită de null.error: error aruncă imediat IllegalStateException cu un mesaj; TODO marchează cod încă nescris și aruncă NotImplementedError.runCatching: Rulează un bloc și prinde orice excepție într-un Result; valoarea se scoate cu getOrNull, getOrElse sau getOrThrow.