Come gestire correttamente le eccezioni in Kotlin?
sobes.tech AI
Risposta dell'AI
In Kotlin, la gestione delle eccezioni avviene tramite la costruzione try...catch...finally. È possibile chiamare funzioni annotate con @Throws per interagire con codice Java.
fun readFile(path: String): String {
return try {
// Tentativo di eseguire codice rischioso
java.io.File(path).readText()
} catch (e: java.io.IOException) {
// Gestione di un'eccezione specifica
println("Errore durante la lettura del file: ${e.message}")
"" // Valore di default in caso di errore
} finally {
// Blocco che viene sempre eseguito, indipendentemente dall'eccezione
println("Lettura del file completata")
}
}
È possibile usare più blocchi catch per gestire diversi tipi di eccezioni:
fun processData(data: String) {
try {
// Codice che può generare NumberFormatException o NullPointerException
val number = data.toInt()
println("Numero: $number")
} catch (e: NumberFormatException) {
println("Formato numero non valido: ${e.message}")
} catch (e: NullPointerException) {
println("Dati nulli ricevuti: ${e.message}")
}
}
Kotlin non ha eccezioni checked come Java. Le funzioni possono dichiarare che possono lanciare eccezioni usando @Throws, ma non è obbligatorio.
Per casi in cui una funzione può terminare con successo o errore, si usano spesso classi sealed o il tipo Result (nelle versioni sperimentali di Kotlin) invece delle eccezioni, specialmente nel codice asincrono.
Esempio con classe 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("Divisione per zero")
}
Success(a / b)
} catch (e: Throwable) {
Error(e)
}
}
// Uso:
fun processDivision() {
when (val divisionResult = safelyDivide(10, 0)) {
is Success -> println("Risultato: ${divisionResult.value}")
is Error -> println("Errore: ${divisionResult.exception.message}")
}
}
È importante catturare solo le eccezioni che si possono gestire. Evitare blocchi catch vuoti. Se necessario, si può registrare l'eccezione nel log.
È anche possibile lanciare eccezioni esplicitamente usando la parola chiave throw:
fun requirePositive(number: Int) {
if (number <= 0) {
throw IllegalArgumentException("Il numero deve essere positivo")
}
}