Обработка ошибок
Учимся обрабатывать сбои, не давая программе аварийно завершиться.
Исключение (exception) — объект, описывающий ошибку времени выполнения; его «бросают» при сбое и «ловят», чтобы обработать.
Программы сталкиваются с ошибками: неверный ввод, отсутствующий файл, деление на ноль. Чтобы такие ситуации не «роняли» приложение, их обрабатывают через механизм исключений.
try / catch / finally
Код, способный бросить исключение, помещают в try. Блок catch ловит ошибку, а finally выполняется в любом случае.
fun main() {
try {
val n = "abc".toInt() // бросит исключение
println(n)
} catch (e: NumberFormatException) {
println("Не число!")
} finally {
println("Готово")
}
}Вывод:
Не число! Готово
try как выражение
Как и if/when, try в Kotlin — выражение и возвращает значение. Это позволяет аккуратно подставить запасной результат.
fun parseOrZero(s: String): Int {
return try {
s.toInt()
} catch (e: NumberFormatException) {
0
}
}
fun main() {
println(parseOrZero("42"))
println(parseOrZero("oops"))
}Вывод:
42 0
Бросаем собственные исключения
Своё исключение бросают оператором throw. Часто это делают при недопустимых аргументах.
fun divide(a: Int, b: Int): Int {
if (b == 0) throw IllegalArgumentException("Деление на ноль")
return a / b
}
fun main() {
println(divide(10, 2))
try {
divide(5, 0)
} catch (e: IllegalArgumentException) {
println("Поймано: ${e.message}")
}
}Вывод:
5 Поймано: Деление на ноль
Как работает под капотом
Важное отличие от Java: в Kotlin нет проверяемых исключений (checked exceptions). Компилятор не заставляет объявлять или ловить исключения — это решение остаётся за вами. Когда исключение брошено, выполнение текущего блока прерывается и управление «всплывает» вверх по цепочке вызовов до ближайшего подходящего catch. Если такого нет, программа завершится с ошибкой. Удобная альтернатива исключениям для ожидаемых сбоев — возвращать nullable-результат или sealed-тип с вариантами Success/Error.
Частые ошибки
- Глотать исключение пустым
catch. Ошибка исчезнет незаметно — как минимум залогируйте её. - Ловить слишком общий тип. Лучше ловить конкретное исключение, а не
Exceptionвообще. - Использовать исключения для обычной логики. Для ожидаемых случаев предпочтительнее nullable или
sealed-результат.
Итог
- Рискованный код оборачивают в
try, ошибку ловят вcatch,finallyвыполняется всегда. try— выражение и может возвращать значение.- Собственное исключение бросают через
throw. - В Kotlin нет проверяемых исключений; для ожидаемых сбоев удобны nullable и
sealed-типы.