← Назад к вопросам

Можно ли пометить функцию в Kotlin что она выбрасывает исключение?

1.0 Junior🔥 61 комментариев
#Kotlin основы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Можно ли пометить функцию в Kotlin, что она выбрасывает исключение?

Краткий ответ: В отличие от Java, в Kotlin нет встроенной аннотации или ключевого слова (аналога throws), чтобы явно пометить функцию как бросающую исключение. Однако существуют альтернативные подходы и идиоматические способы обработки исключений, которые соответствуют философии языка.

Почему в Kotlin нет аналога throws?

  1. Проверяемые исключения (checked exceptions) не поддерживаются — это сознательное дизайнерское решение. В Java проверяемые исключения часто приводят к шаблонному коду (множеству try-catch) и могут маскировать реальные ошибки. Kotlin предпочитает непроверяемые исключения, что упрощает код и дает больше гибкости.
  2. Акцент на null-safety и типизированные результаты — вместо исключений для ожидаемых ошибок (например, парсинг числа, работа с сетью) рекомендуется использовать Result<T>, sealed class или nullable-типы.

Как обозначить, что функция может выбросить исключение?

Хотя явной пометки нет, можно использовать следующие подходы:

1. Документация (KDoc)

Самый простой способ — задокументировать исключения в комментариях с помощью @throws:

/**
 * Парсит строку в число.
 * @throws NumberFormatException если строка не является числом.
 */
fun parseNumber(str: String): Int {
    return str.toInt()
}

2. Использование @Throws для совместимости с Java

Если функция вызывается из Java-кода, используйте аннотацию @Throws:

import java.io.IOException

@Throws(IOException::class)
fun readFile(path: String): String {
    // Может бросить IOException
    return File(path).readText()
}

В Java такой метод будет объявлен с throws IOException.

3. Возврат Result<T> (рекомендуемый способ)

Для функций, где ошибки — часть ожидаемого поведения, используйте Result<T>:

fun safeParseNumber(str: String): Result<Int> = runCatching {
    str.toInt()
}

// Использование
val result = safeParseNumber("123")
result.onSuccess { println(it) }
      .onFailure { e -> println("Ошибка: ${e.message}") }

4. sealed class для типизированных ошибок

Для сложных сценариев с разными типами ошибок:

sealed class ParseResult {
    data class Success(val value: Int) : ParseResult()
    data class Error(val reason: String) : ParseResult()
}

fun parseInput(input: String): ParseResult {
    return try {
        ParseResult.Success(input.toInt())
    } catch (e: NumberFormatException) {
        ParseResult.Error("Неверный формат числа")
    }
}

Ключевые рекомендации по исключениям в Kotlin

  • Используйте исключения только для неожиданных ошибок (например, ошибки программиста, сбои в системе). Для ожидаемых ошибок предпочитайте возврат результата через Result или sealed class.
  • Ловите исключения там, где можете их обработать — не злоупотребляйте try-catch на верхнем уровне.
  • Для Java-совместимости всегда используйте @Throws, если ваша Kotlin-функция бросает проверяемые исключения и вызывается из Java.

Пример сравнения подходов

// Способ 1: Исключение (для критических ошибок)
fun divide(a: Int, b: Int): Int {
    if (b == 0) throw ArithmeticException("Деление на ноль")
    return a / b
}

// Способ 2: Result (для ожидаемых ошибок)
fun divideSafe(a: Int, b: Int): Result<Int> = runCatching {
    if (b == 0) throw ArithmeticException("Деление на ноль")
    a / b
}

// Способ 3: Nullable (для простых случаев)
fun divideOrNull(a: Int, b: Int): Int? {
    return if (b != 0) a / b else null
}

Вывод: В Kotlin нет прямой пометки функций на исключения, но это компенсируется более выразительными конструкциями для обработки ошибок. Выбор подхода зависит от контекста: используйте исключения для невосстановимых ошибок, а Result или типизированные классы — для ожидаемых сбоев. Для Java-интеграции применяйте аннотацию @Throws.

Можно ли пометить функцию в Kotlin что она выбрасывает исключение? | PrepBro