Исключения
Классы исключений
Все классы исключений в Kotlin наследуются от класса Throwable. Каждое исключение имеет сообщение, стек вызовов и необязательную причину.
Для создания объекта исключения используйте выражение throw:
fun main() {
//sampleStart
throw Exception("Hi There!")
//sampleEnd
}
Для перехвата исключения используйте выражение try, ..., catch:
try {
// some code
} catch (e: SomeException) {
// handler
} finally {
// optional finally block
}
Может быть ноль или более блоков catch, и блок finally может быть опущен. Однако, требуется по крайней мере один блок catch или finally.
Try — это выражение
Выражение try является выражением, что означает, что оно может иметь возвращаемое значение:
val a: Int? = try { input.toInt() } catch (e: NumberFormatException) { null }
Возвращаемое значение выражения try — это либо последнее выражение в блоке try, либо последнее выражение в блоке catch (или блоках). Содержимое блока finally не влияет на результат выражения.
Исключения, требующие обработки
В Kotlin нет проверочных исключений. Причин этому несколько, но мы предоставим простой пример, который иллюстрирует эту особенность.
Ниже приведён пример интерфейса из JDK, реализованного классом StringBuilder:
Appendable append(CharSequence csq) throws IOException;
Эта сигнатура означает, что каждый раз, когда я добавляю строку к чему-либо (например, к журналу, консоли и т. д.), я должен перехватывать исключение IOExceptions. Почему? Потому что реализация может выполнять операции ввода-вывода (класс Writer также реализует Appendable). В результате подобный код встречается повсюду:
try {
log.append(message)
} catch (IOException e) {
// Must be safe
}
И это не хорошо. Просто взгляните на Effective Java, 3-е издание, пункт 77: Не игнорируйте исключения.
Брюс Эккель так говорит об исключениях, требующих обработки:
И вот некоторые дополнительные мысли по этому вопросу:
Исключения, требующие обработки в Java, были ошибкой (Род Вальдхофф)
Проблемы с проверочными исключениями (Андерс Хейлсберг)
Если вы хотите предупредить вызывающие стороны о возможных исключениях при вызове кода Kotlin из Java, Swift или Objective-C, вы можете использовать аннотацию @Throws. Дополнительную информацию об использовании этой аннотации см. для Java и для Swift и Objective-C.
Тип Nothing
Тип throw — это выражение в Kotlin, поэтому вы можете использовать его, например, в части выражения Elvis:
val s = person.name ?: throw IllegalArgumentException("Name required")
Выражение throw имеет тип Nothing. Этот тип не имеет значений и используется для обозначения мест в коде, которые никогда не могут быть достигнуты. В собственном коде вы можете использовать Nothing для обозначения функции, которая никогда не возвращает значение:
fun fail(message: String): Nothing {
throw IllegalArgumentException(message)
}
При вызове этой функции компилятор будет знать, что выполнение не продолжается после вызова:
val s = person.name ?: fail("Name required")
println(s) // 's' is known to be initialized at this point
Вы также можете столкнуться с этим типом при работе с выводом типов. Нулевая версия этого типа, Nothing?, имеет ровно одно возможное значение — null. Если вы используете null для инициализации значения выведенного типа, и нет другой информации, которая может быть использована для определения более конкретного типа, компилятор выведет тип Nothing?:
val x = null // 'x' has type `Nothing?` val l = listOf(null) // 'l' has type `List<Nothing?>
Взаимодействие с Java
Дополнительную информацию о взаимодействии с Java, включая исключения, см. в разделе «Исключения» на странице взаимодействия с Java.
© 2010–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/exceptions.html