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

Как понять исключение проверяемое или непроверяемое

1.3 Junior🔥 191 комментариев
#Основы Java

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

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

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

Как Отличить Checked Exception от Unchecked

Значение экстремально важно в Java, так как оно определяет требование компилятора к обработке ошибок. Вот надёжные способы понять, проверяемо ли исключение или нет.

Способ 1: Иерархия Наследования

Основной критерий: посмотри на родительский класс

java.lang.Throwable
├── java.lang.Exception
│   ├── java.lang.RuntimeException (Unchecked)
│   │   ├── NullPointerException
│   │   ├── IndexOutOfBoundsException
│   │   ├── IllegalArgumentException
│   │   └── ...
│   └── Остальные (Checked)
│       ├── IOException
│       ├── SQLException
│       ├── ClassNotFoundException
│       └── ...
└── java.lang.Error (Unchecked)
    ├── StackOverflowError
    ├── OutOfMemoryError
    └── ...

Правило:

  • Extends RuntimeException → Unchecked (непроверяемое)
  • Extends Exception (но не RuntimeException) → Checked (проверяемое)
  • Extends Error → Unchecked (непроверяемое)

Способ 2: Проверка в IDE

IntelliJ IDEA:

// Кликни на имя исключения и посмотри иерархию
throw new IOException("File not found");
// CTRL+B или кликни на IOException
// Увидишь: public class IOException extends Exception
// → Это Checked Exception

throw new NullPointerException("null reference");
// CTRL+B
// Увидишь: public class NullPointerException extends RuntimeException
// → Это Unchecked Exception

Способ 3: Требование Компилятора

Самый практичный способ — попробуй скомпилировать:

// Checked Exception — КОМПИЛЯТОР ТРЕБУЕТ ОБРАБОТКИ
public void readFile() {
    // ❌ ОШИБКА КОМПИЛЯЦИИ
    FileInputStream fis = new FileInputStream("file.txt");
}

// Нужно либо ловить, либо объявлять в throws
public void readFile() throws FileNotFoundException {
    // ✓ OK — объявили в throws
    FileInputStream fis = new FileInputStream("file.txt");
}

// Или ловить
public void readFile() {
    try {
        FileInputStream fis = new FileInputStream("file.txt");
    } catch (FileNotFoundException e) {
        // ✓ OK — словили
    }
}

// Unchecked Exception — КОМПИЛЯТОР НЕ ТРЕБУЕТ
public void process(String[] array) {
    // ✓ OK — даже без try-catch
    String element = array[10];  // Может выбросить IndexOutOfBoundsException
    
    // ✓ OK — даже без throws
    int value = Integer.parseInt("abc");  // Может выбросить NumberFormatException
}

Способ 4: Справочная Таблица Часто Встречаемых

╔════════════════════════════════════╦═══════════╗
║           Исключение               ║   Тип     ║
╠════════════════════════════════════╬═══════════╣
║ IOException                        ║ Checked   ║
║ FileNotFoundException               ║ Checked   ║
║ SQLException                        ║ Checked   ║
║ ClassNotFoundException              ║ Checked   ║
║ InterruptedException                ║ Checked   ║
║ ReflectiveOperationException        ║ Checked   ║
║ ParseException                      ║ Checked   ║
║ Exception (сам по себе)             ║ Checked   ║
╠════════════════════════════════════╬═══════════╣
║ NullPointerException                ║ Unchecked ║
║ IndexOutOfBoundsException           ║ Unchecked ║
║ IllegalArgumentException            ║ Unchecked ║
║ IllegalStateException               ║ Unchecked ║
║ ClassCastException                  ║ Unchecked ║
║ NumberFormatException               ║ Unchecked ║
║ ArithmeticException                 ║ Unchecked ║
║ UnsupportedOperationException       ║ Unchecked ║
║ ConcurrentModificationException     ║ Unchecked ║
║ NoSuchElementException              ║ Unchecked ║
║ RuntimeException (сам по себе)      ║ Unchecked ║
║ Error (и подклассы)                 ║ Unchecked ║
╚════════════════════════════════════╩═══════════╝

Способ 5: Читаемая Документация

JavaDoc обычно указывает:

/**
 * @throws IOException если файл не найден или неудачное чтение
 * @throws IllegalArgumentException если path пуста
 * @throws NullPointerException если path == null
 */
public String readFile(String path) throws IOException {
    if (path == null) {
        throw new NullPointerException("path cannot be null");
    }
    if (path.isEmpty()) {
        throw new IllegalArgumentException("path cannot be empty");
    }
    // ...
}

// Анализируем:
// - @throws IOException без указания, что ловить → Checked (объявлена в throws)
// - @throws IllegalArgumentException → Unchecked (не требует обработки)
// - @throws NullPointerException → Unchecked (не требует обработки)

Способ 6: Проверка в Runtime

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

public class ExceptionTypeChecker {
    
    public static boolean isChecked(Class<? extends Throwable> exceptionClass) {
        // Checked исключение не должно быть подклассом RuntimeException
        return !RuntimeException.class.isAssignableFrom(exceptionClass)
               && !Error.class.isAssignableFrom(exceptionClass)
               && Throwable.class.isAssignableFrom(exceptionClass);
    }
    
    public static void main(String[] args) {
        System.out.println(isChecked(IOException.class));               // true
        System.out.println(isChecked(SQLException.class));             // true
        System.out.println(isChecked(NullPointerException.class));     // false
        System.out.println(isChecked(IllegalArgumentException.class)); // false
        System.out.println(isChecked(OutOfMemoryError.class));         // false
    }
}

Практические Примеры

Пример 1: Определение из Кода

// Задача: определи тип этого исключения
public void processData(String data) throws DataProcessingException {
    // Смотрим определение DataProcessingException
}

// Если в коде DataProcessingException.java:
public class DataProcessingException extends Exception { }  // Checked

// Или:
public class DataProcessingException extends RuntimeException { }  // Unchecked

Пример 2: Из Сигнатуры Метода

// В методе указан throws IOException?
// → IOException — Checked Exception
public void readFile(String path) throws IOException { }

// В методе НЕ указан throws, но может быть исключение?
// → Скорее всего Unchecked
public void process(List<String> items) {
    // IndexOutOfBoundsException может быть, но не в throws
    String first = items.get(0);
}

Как Запомнить

Мнемоника:

  • Checked = Контракт — ты ОБЯЗАН обработать (в throws или try-catch)
  • Unchecked = Контроль программиста — это ошибка твоего кода

Вопрос на запоминание:

  • Может ли это произойти при ПРАВИЛЬНОМ использовании API?
    • ДА → Checked Exception (IOException при отсутствии файла)
    • НЕТ → Unchecked Exception (NullPointerException — ошибка программиста)

Интерактивная Проверка

public class QuickCheckException {
    // Самый быстрый способ: создай переменную и посмотри
    
    public static void main(String[] args) {
        // Unchecked — скомпилируется
        try {
            throw new NullPointerException();
        } catch (NullPointerException e) { }
        
        // Checked — НЕ скомпилируется без обработки
        // throw new IOException();  // ОШИБКА КОМПИЛЯЦИИ!
        // Нужно:
        try {
            throw new IOException();
        } catch (IOException e) { }
    }
}

Итоговое Резюме

Быстрая проверка исключения:

  1. В IDE: кликни на исключение → посмотри extends RuntimeException?

    • YES → Unchecked
    • NO → Checked
  2. В коде: компилятор требует try-catch или throws?

    • YES → Checked
    • NO → Unchecked
  3. В памяти: запомни частые примеры (IOException, SQLException = Checked; NullPointerException, IllegalArgumentException = Unchecked)

Этот навык критичен для любого Java разработчика, так как неправильная обработка исключений ведёт к нестабильному коду.