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

Для чего нужно unchecked исключение?

1.7 Middle🔥 231 комментариев
#Основы Java

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

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

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

# Unchecked Исключение (Unchecked Exception)

Определение

Unchecked исключение (или runtime исключение) — это исключение, которое не обязательно перехватывать или объявлять в сигнатуре метода. Компилятор Java не проверяет, обработано ли такое исключение. Unchecked исключение наследуется от класса RuntimeException.

Основное назначение

1. Различие между Checked и Unchecked исключениями

// CHECKED исключение (наследуется от Exception, но НЕ RuntimeException)
public class FileNotFoundException extends IOException { }

// Компилятор ТРЕБУЕТ обработку
public void readFile() throws FileNotFoundException {  // Обязательно throws
    throw new FileNotFoundException("File not found");
}

// UNCHECKED исключение (наследуется от RuntimeException)
public class InvalidAgeException extends RuntimeException { }

// Компилятор НЕ требует обработки
public void setAge(int age) {  // Можно БЕЗ throws
    if (age < 0) {
        throw new InvalidAgeException("Age cannot be negative");
    }
}

2. Иерархия исключений

Throwable
├── Error (серьёзные ошибки JVM)
│   ├── OutOfMemoryError
│   ├── StackOverflowError
│   └── VirtualMachineError
│
└── Exception
    ├── CHECKED исключения (наследуют Exception напрямую)
    │   ├── IOException
    │   ├── SQLException
    │   ├── FileNotFoundException
    │   └── ...
    │
    └── RuntimeException (UNCHECKED исключения)
        ├── NullPointerException
        ├── ArrayIndexOutOfBoundsException
        ├── IllegalArgumentException
        ├── ArithmeticException
        ├── ClassCastException
        └── ...

3. Когда использовать Unchecked исключения

Unchecked исключение для ошибок программиста:

// NullPointerException — ошибка программиста (забыл проверить null)
public String getName(User user) {
    return user.getName();  // Если user == null, то NPE (unchecked)
}

// ArrayIndexOutOfBoundsException — ошибка программиста (неправильный индекс)
public int getElement(int[] arr, int index) {
    return arr[index];  // Если index >= arr.length, то исключение (unchecked)
}

// IllegalArgumentException — некорректный аргумент
public void setAge(int age) {
    if (age < 0) {
        throw new IllegalArgumentException("Age must be positive");
    }
    this.age = age;
}

Checked исключение для ошибок окружения:

// IOException — ошибка окружения (файла или сети)
public String readFile(String path) throws IOException {
    FileReader reader = new FileReader(path);  // Требует обработки
    // ...
}

// SQLException — ошибка окружения (БД недоступна)
public List<User> getAllUsers() throws SQLException {
    Connection conn = getConnection();  // Требует обработки
    // ...
}

4. Преимущества Unchecked исключений

Чистый код:

// С UNCHECKED исключениями
public int divide(int a, int b) {
    return a / b;  // ArithmeticException если b==0 (unchecked)
}

// Vs с CHECKED исключениями (переусложненно)
public int divide(int a, int b) throws DivisionByZeroException {
    if (b == 0) throw new DivisionByZeroException();
    return a / b;
}

// Вызывающий код
try {
    int result = divide(10, 0);
} catch (DivisionByZeroException e) {
    // Обработка
}

Распространение ошибки:

// Unchecked исключения распространяются автоматически
public User getUser(int id) {  // Нет throws
    User user = findById(id);
    if (user == null) {
        throw new IllegalArgumentException("User not found");  // NPE распространится
    }
    return user;
}

// Вызывающий код может обработать или нет
User user = getUser(1);  // Без try-catch
try {
    user = getUser(1);
} catch (IllegalArgumentException e) {
    System.out.println("Error: " + e.getMessage());
}

5. Создание собственного Unchecked исключения

// Наследуем от RuntimeException (не от Exception!)
public class InsufficientBalanceException extends RuntimeException {
    public InsufficientBalanceException(String message) {
        super(message);
    }
    
    public InsufficientBalanceException(String message, Throwable cause) {
        super(message, cause);
    }
}

public class BankAccount {
    private double balance;
    
    public void withdraw(double amount) {
        if (amount > balance) {
            throw new InsufficientBalanceException(
                "Balance is " + balance + ", requested " + amount
            );  // Не требует throws в сигнатуре
        }
        balance -= amount;
    }
}

// Использование
BankAccount account = new BankAccount(100);
account.withdraw(50);   // OK
account.withdraw(60);   // Throws InsufficientBalanceException

6. Примеры Unchecked исключений

// NullPointerException
String name = null;
int length = name.length();  // NPE!

// ArrayIndexOutOfBoundsException
int[] arr = {1, 2, 3};
int value = arr[10];  // IndexOutOfBoundsException!

// ArithmeticException
int result = 10 / 0;  // ArithmeticException!

// ClassCastException
Object obj = "string";
Integer num = (Integer) obj;  // ClassCastException!

// IllegalArgumentException
Thread thread = new Thread(null);  // IllegalArgumentException!

// IllegalStateException
List<Integer> list = Collections.unmodifiableList(new ArrayList<>());
list.add(1);  // UnsupportedOperationException!

// NumberFormatException
int num = Integer.parseInt("abc");  // NumberFormatException!

7. Сравнение Checked vs Unchecked

ПараметрCheckedUnchecked
НаследникExceptionRuntimeException
Проверка компиляторомДа (обязательно)Нет
throws в сигнатуреОбязателенНе требуется
try-catchОбязателенОпционален
ИспользованиеОшибки окруженияОшибки программиста
ПримерIOExceptionNullPointerException

8. Обработка Unchecked исключений

// Опция 1: Не обрабатывать (распространяется вверх)
public void process() {
    String str = null;
    str.length();  // NPE распространится
}

// Опция 2: Перехватить и обработать
public void process() {
    try {
        String str = null;
        str.length();
    } catch (NullPointerException e) {
        System.out.println("Got NPE: " + e);
    }
}

// Опция 3: Перехватить и обернуть
public void process() throws CustomException {
    try {
        String str = null;
        str.length();
    } catch (NullPointerException e) {
        throw new CustomException("Processing failed", e);
    }
}

// Опция 4: Лучший подход — предотвратить
public void process(String str) {
    if (str == null) {
        throw new IllegalArgumentException("String cannot be null");
    }
    str.length();
}

9. Лучшие практики

ДА — используй Unchecked для:

// Ошибки программиста
if (user == null) {
    throw new IllegalArgumentException("User cannot be null");
}

if (age < 0) {
    throw new IllegalArgumentException("Age must be positive");
}

if (items.isEmpty()) {
    throw new IllegalStateException("Items list is empty");
}

НЕТ — не используй Unchecked для:

// Ошибки окружения должны быть CHECKED
public void readFile(String path) {
    // НЕПРАВИЛЬНО:
    // throw new RuntimeException("File not found");  // Плохо!
    
    // ПРАВИЛЬНО:
    // throws IOException {  // Хорошо!
    //     FileReader reader = new FileReader(path);
    // }
}

Выводы

Unchecked исключение нужно для:

  • Обозначения ошибок программиста, которые можно было предотвратить
  • Избежания переусложнения API checked исключениями
  • Распространения исключений без боязни забыть обработать
  • Указания на то, что ошибка логическая, а не внешняя

Оно НЕ заменяет Checked исключения, а дополняет их для разных сценариев. Правило простое: ошибки окружения → checked, ошибки программиста → unchecked.