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

Что такое исключения?

1.6 Junior🔥 172 комментариев
#Kotlin основы#Архитектура и паттерны

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

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

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

Что такое исключения?

Исключение — это событие, возникающее во время выполнения программы, которое нарушает нормальный поток инструкций. В контексте Android-разработки на Java/Kotlin исключения представляют собой объекты специальных классов, которые "бросаются" (thrown) при возникновении ошибок или нестандартных ситуаций (например, деление на ноль, попытка доступа к файлу, который не существует, или обращение к null-ссылке).

Исключения являются ключевым механизмом обработки ошибок, позволяющим отделить код, выполняющий основную логику, от кода, отвечающего за обработку сбоев. Это делает программы более устойчивыми, понятными и удобными для поддержки.

Иерархия исключений в Java/Kotlin

В основе иерархии лежит класс Throwable. От него наследуются два основных подкласса:

  1. Error (Ошибка): Представляет собой критические проблемы, которые приложение обычно не должно пытаться обрабатывать (например, OutOfMemoryError, StackOverflowError). Они связаны с самим исполняющим окружением (JVM).

  2. Exception (Исключение): Это базовый класс для большинства проблем, с которыми сталкивается приложение. Его, в свою очередь, делят на:

    *   **Проверяемые исключения (`Checked Exceptions`)**: Классы-наследники `Exception`, но не `RuntimeException`. Компилятор **обязательно проверяет**, обработаны ли они. Если метод может выбросить такое исключение, он должен либо объявить его в сигнатуре с помощью `throws`, либо обработать в блоке `try-catch`.
    ```java
    // Java пример проверяемого исключения
    public void readFile() throws IOException {
        FileReader file = new FileReader("file.txt");
        // ... операции с файлом
    }
    ```
    *   **Непроверяемые исключения (`Unchecked Exceptions`)**: Наследники класса `RuntimeException`. Компилятор не требует их обязательной обработки или объявления. Часто это ошибки программирования (логические ошибки или неправильное использование API).
    ```kotlin
    // Kotlin пример непроверяемого исключения
    fun calculateDivision(a: Int, b: Int): Int {
        return a / b // При b = 0 выбросится ArithmeticException
    }
    ```

Механизм работы: try-catch-finally

Основной инструмент для управления исключениями — конструкция try-catch-finally.

  • Блок try: Содержит код, в котором потенциально может возникнуть исключение.
  • Блок(и) catch: Определяют, как обрабатывать исключения определенных типов. Можно перехватывать несколько разных исключений последовательно.
  • Блок finally: Опциональный блок, который выполняется всегда, независимо от того, было выброшено исключение или нет. Здесь обычно размещают код для освобождения ресурсов (закрытие файлов, сетевых соединений, курсоров БД).
// Пример на Kotlin для Android
fun loadNetworkData(url: String) {
    var connection: HttpURLConnection? = null
    try {
        val urlObj = URL(url)
        connection = urlObj.openConnection() as HttpURLConnection
        connection.connectTimeout = 5000
        val inputStream = connection.inputStream
        // ... чтение данных (здесь может быть IOException)
        Log.d("Network", "Данные успешно загружены")
    } catch (e: IOException) {
        // Ловим конкретное исключение (проверяемое)
        Log.e("Network", "Ошибка сети или ввода-вывода", e)
        // Показываем пользователю понятное сообщение
        showErrorToast("Не удалось загрузить данные. Проверьте подключение.")
    } catch (e: RuntimeException) {
        // Ловим более общий тип непроверяемых исключений
        Log.e("Network", "Неожиданная ошибка выполнения", e)
    } finally {
        // Гарантированно закрываем соединение, даже если была ошибка
        connection?.disconnect()
        Log.d("Network", "Ресурсы соединения освобождены")
    }
}

Особенности и лучшие практики в Android-разработке

  • Избегайте пустых блоков catch: "Заглушка" исключения без логирования или реакции — антипаттерн, который приводит к трудноотлавливаемым багам.
  • Используйте конкретные типы исключений: Не ловите всегда общий Exception. Это помогает точнее диагностировать проблему.
  • Логируйте исключения: Всегда записывайте стек-трейс (e.printStackTrace() или, лучше, используя логгеры вроде Log.e()), это критически важно для отладки.
  • Не злоупотребляйте проверяемыми исключениями для контроля потока: В Kotlin их использование сведено к минимуму, а во многих современных подходах предпочтение отдается специальным типам-результатам (Result<T>, Either) или исключениям только для действительно исключительных ситуаций.
  • Обработка на уровне UI/Потоков: В Android исключения, выброшенные в главном потоке (UI Thread) и не перехваченные, приводят к падению приложения (ANR — если поток блокируется, или Crash). Используйте try-catch в критических участках кода, а также устанавливайте глобальные обработчики неперехваченных исключений через Thread.setDefaultUncaughtExceptionHandler для отправки отчетов об ошибках (например, в Crashlytics).

Понимание исключений и грамотное их использование — фундаментальный навык Android-разработчика, напрямую влияющий на стабильность и пользовательский опыт вашего приложения.

Что такое исключения? | PrepBro