Как правильно обрабатывать исключения в Kotlin?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
В Kotlin для обработки исключений используется конструкция try...catch...finally. Можно вызывать функции, помеченные как @Throws для взаимодействия с Java-кодом.
fun readFile(path: String): String {
return try {
// Попытка выполнить опасный код
java.io.File(path).readText()
} catch (e: java.io.IOException) {
// Обработка конкретного исключения
println("Ошибка при чтении файла: ${e.message}")
"" // Возвращаем значение по умолчанию в случае ошибки
} finally {
// Блок, который выполняется всегда, независимо от исключения
println("Попытка чтения файла завершена")
}
}
Можно использовать несколько блоков catch для обработки разных типов исключений:
fun processData(data: String) {
try {
// Некий код, который может вызвать NumberFormatException или NullPointerException
val number = data.toInt()
println("Число: $number")
} catch (e: NumberFormatException) {
println("Неверный формат числа: ${e.message}")
} catch (e: NullPointerException) {
println("Получены нулевые данные: ${e.message}")
}
}
Kotlin не имеет checked-исключений, как в Java. Функции могут объявлять, что они могут выбрасывать исключения с помощью @Throws, но это необязательно для Kotlin-кода.
Для случаев, когда функция может завершиться успехом или ошибкой, часто применяют sealed-классы или Result-тип (в экспериментальных версиях Kotlin) instead of исключений, особенно в асинхронном коде.
Пример с 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("Деление на ноль")
}
Success(a / b)
} catch (e: Throwable) {
Error(e)
}
}
// Использование:
fun processDivision() {
when (val divisionResult = safelyDivide(10, 0)) {
is Success -> println("Результат: ${divisionResult.value}")
is Error -> println("Ошибка: ${divisionResult.exception.message}")
}
}
Важно перехватывать только те исключения, которые вы можете обработать. Не стоит использовать пустые блоки catch. При необходимости, можно записать информацию об исключении в лог.
Также можно выбрасывать исключения явно с помощью ключевого слова throw:
fun requirePositive(number: Int) {
if (number <= 0) {
throw IllegalArgumentException("Число должно быть положительным")
}
}