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

Назови исключения, не требующие обработки

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

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

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

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

Ответ на вопрос об исключениях, не требующих обработки

Исключения делятся на две категории: Checked и Unchecked

В Java существуют исключения, которые не требуют обязательной обработки (unchecked exceptions) и исключения, которые требуют обработки (checked exceptions). Различие основано на том, выброшены ли они во время компиляции или выполнения.

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

Throwable
├── Exception
│   ├── Checked Exceptions (требуют обработки)
│   │   ├── IOException
│   │   ├── SQLException
│   │   ├── FileNotFoundException
│   │   └── ...
│   │
│   └── RuntimeException (не требуют обработки)
│       ├── NullPointerException
│       ├── IndexOutOfBoundsException
│       ├── IllegalArgumentException
│       ├── ArithmeticException
│       └── ...
│
└── Error (не требуют обработки)
    ├── OutOfMemoryError
    ├── StackOverflowError
    ├── VirtualMachineError
    └── ...

1. Unchecked Exceptions (RuntimeException)

Unchecked исключения — это исключения, которые не требуют обработки и наследуются от RuntimeException. Они возникают из-за логических ошибок в коде во время выполнения.

NullPointerException

public void processUser(User user) {
    // Не требует обработки, хотя может быть выброшена
    String name = user.getName(); // NPE если user == null
}

// Хорошая практика — проверить перед использованием
public void processUserSafe(User user) {
    if (user != null) {
        String name = user.getName();
    }
}

ArrayIndexOutOfBoundsException

public void accessArray(int[] array, int index) {
    // Не требует обработки, но может быть выброшена
    int value = array[index]; // Если index >= array.length
}

// Хорошая практика — проверить границы
public void accessArraySafe(int[] array, int index) {
    if (index >= 0 && index < array.length) {
        int value = array[index];
    }
}

StringIndexOutOfBoundsException

public void getCharacter(String text, int index) {
    // Не требует обработки
    char c = text.charAt(index); // Может быть выброшена
}

public void getCharacterSafe(String text, int index) {
    if (index >= 0 && index < text.length()) {
        char c = text.charAt(index);
    }
}

ClassCastException

public void castObject(Object obj) {
    // Не требует обработки
    String str = (String) obj; // CCE если obj не String
}

// Хорошая практика — проверить тип перед кастингом
public void castObjectSafe(Object obj) {
    if (obj instanceof String) {
        String str = (String) obj;
    }
}

IllegalArgumentException

public void setAge(int age) {
    // Не требует обработки, но может быть выброшена
    if (age < 0) {
        throw new IllegalArgumentException("Age cannot be negative");
    }
    this.age = age;
}

// Вызов — не требует try-catch
public void createUser(int age) {
    setAge(age); // Обработка зависит от логики
}

NumberFormatException

public int parseNumber(String str) {
    // Не требует обработки
    return Integer.parseInt(str); // Может быть выброшена
}

// Хорошая практика — валидировать входные данные
public Integer parseNumberSafe(String str) {
    if (str == null || str.isEmpty()) {
        return null;
    }
    try {
        return Integer.parseInt(str);
    } catch (NumberFormatException e) {
        return null; // или логировать
    }
}

ArithmeticException

public int divide(int a, int b) {
    // Не требует обработки
    return a / b; // Может быть выброшена если b == 0
}

// Хорошая практика — проверить условие
public Integer divideSafe(int a, int b) {
    if (b == 0) {
        return null; // или выбросить исключение с понятным сообщением
    }
    return a / b;
}

UnsupportedOperationException

public class ImmutableList<T> {
    private List<T> items;
    
    public List<T> getItems() {
        // Не требует обработки
        return Collections.unmodifiableList(items);
    }
}

// Использование
List<String> list = Collections.unmodifiableList(Arrays.asList("a", "b"));
list.add("c"); // Выбросит UnsupportedOperationException

ConcurrentModificationException

public void iterateList(List<String> items) {
    // Не требует обработки
    for (String item : items) {
        if (item.startsWith("a")) {
            items.remove(item); // Может выбросить CME
        }
    }
}

// Хорошая практика — использовать Iterator
public void iterateListSafe(List<String> items) {
    Iterator<String> iterator = items.iterator();
    while (iterator.hasNext()) {
        String item = iterator.next();
        if (item.startsWith("a")) {
            iterator.remove(); // Безопасно
        }
    }
}

2. Errors (не требуют обработки)

Errors — это серьёзные проблемы JVM, которые не следует перехватывать (хотя технически это возможно). Они указывают на критические сбои.

OutOfMemoryError

public void outOfMemory() {
    // Не требует обработки (нечего ловить)
    List<byte[]> list = new ArrayList<>();
    while (true) {
        list.add(new byte[1024 * 1024]); // Запросим 1MB
    }
    // В какой-то момент: OutOfMemoryError: Java heap space
}

// Нельзя обработать — память закончилась
try {
    // ...
} catch (OutOfMemoryError e) {
    // ❌ Не поможет, памяти нет!
}

StackOverflowError

public int fibonacci(int n) {
    // Не требует обработки
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2); // Может переполнить стек
}

// Вызов большого числа
fibonacci(100000); // StackOverflowError

// Нельзя обработать
try {
    fibonacci(100000);
} catch (StackOverflowError e) {
    // ❌ Стек переполнен, JVM может упасть
}

NoClassDefFoundError

// Если класс не найден при runtime
try {
    Class.forName("com.nonexistent.ClassName");
} catch (ClassNotFoundException e) {
    // Это checked exception, требует обработки
}

// NoClassDefFoundError выбрасывается автоматически
// и не требует обработки

ExceptionInInitializerError

public class BadClass {
    static {
        throw new RuntimeException("Initialization failed");
    }
}

// При загрузке класса будет выброшена ExceptionInInitializerError
// и не требует обработки

Полный список Unchecked Exceptions

// RuntimeException и наследники
NullPointerException
IndexOutOfBoundsException
  ├── ArrayIndexOutOfBoundsException
  └── StringIndexOutOfBoundsException
ClassCastException
IllegalArgumentException
  ├── NumberFormatException
  └── IllegalStateException
ArithmeticException
UnsupportedOperationException
ConcurrentModificationException
EmptyStackException
NoSuchElementException
IllegalMonitorStateException

Полный список Errors

// Error и наследники
OutOfMemoryError
StackOverflowError
VirtualMachineError
  ├── InternalError
  ├── UnknownError
  └── UnknownThreadException
NoClassDefFoundError
ClassNotFoundException (на самом деле это Exception!)
ExceptionInInitializerError
LinkageError
ThreadDeath (deprecated)
AssertionError

Таблица: Требуется ли обработка?

КатегорияТребуетсяПримерыОбработать?
Checked Exception✅ ДАIOException, SQLExceptionОбязательно (try-catch или throws)
RuntimeException❌ НЕТNPE, IndexExceptionОпционально (лучше проверить условие)
Error❌ НЕТOutOfMemoryError, StackOverflowErrorНе перехватывать

Примеры Checked Exceptions (требуют обработки)

Для сравнения, это исключения, которые требуют обработки:

// IOException — требует обработки
public void readFile(String filename) throws IOException {
    FileReader reader = new FileReader(filename); // Выбросит IOException
    reader.read();
}

// SQLException — требует обработки
public void queryDatabase() throws SQLException {
    Connection conn = DriverManager.getConnection(url);
    Statement stmt = conn.createStatement(); // Выбросит SQLException
}

// InterruptedException — требует обработки
public void sleep() throws InterruptedException {
    Thread.sleep(1000); // Выбросит InterruptedException
}

Best Practices

Правильно:

// Для Unchecked exceptions — проверить условие
public void process(List<String> items) {
    if (items != null && !items.isEmpty()) {
        for (String item : items) {
            System.out.println(item);
        }
    }
}

// Для Checked exceptions — обработать или пробросить
public void readFile(String filename) throws IOException {
    try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    } // IOException будет обработан или пробьёт вверх
}

Неправильно:

// Перехватывать Errors
try {
    fibonacci(100000);
} catch (StackOverflowError e) { // ❌ Плохо
    e.printStackTrace();
}

// Перехватывать, но ничего не делать
try {
    Integer.parseInt("abc");
} catch (NumberFormatException e) { // ❌ Подавляет ошибку
    // Ничего
}

// Не обработать checked exception
public void readFile(String filename) {
    // ❌ Ошибка компиляции
    FileReader reader = new FileReader(filename); // Требует обработки
}

Заключение

Исключения, не требующие обработки:

  1. RuntimeException и его наследники (NullPointerException, IndexOutOfBoundsException, IllegalArgumentException и т.д.) — лучше проверить условия, чем ловить

  2. Error и его наследники (OutOfMemoryError, StackOverflowError и т.д.) — не следует перехватывать, они указывают на критические проблемы JVM

Для Checked Exceptions (IOException, SQLException и т.д.) обработка обязательна — компилятор это проверит.

Философия Java: используйте Unchecked Exceptions для программных ошибок (неправильная логика), а Checked Exceptions для проблем, которые вы не можете контролировать (I/O, сеть и т.д.).

Назови исключения, не требующие обработки | PrepBro