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

Какие исключения относятся к Error

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

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

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

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

Исключения категории Error в Java

Error — это класс, который представляет серьёзные проблемы, которые приложение обычно НЕ должно пытаться обработать. Это критические ошибки виртуальной машины Java (JVM) и системы. В отличие от Exception, Error не рекомендуется ловить и обрабатывать — это прерогатива JVM.

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

Throwable
├── Error (серьёзные ошибки JVM)
│   ├── VirtualMachineError
│   │   ├── StackOverflowError
│   │   ├── OutOfMemoryError
│   │   └── UnknownError
│   ├── LinkageError
│   │   ├── ClassNotFoundException
│   │   ├── NoClassDefFoundError
│   │   └── ClassFormatError
│   ├── AssertionError
│   └── ThreadDeath
└── Exception (обрабатываемые исключения)
    ├── RuntimeException (unchecked)
    └── ... (checked exceptions)

Основные Error в Java

1. OutOfMemoryError

Что это: JVM не может выделить память для нового объекта

// ❌ Приводит к OutOfMemoryError
List<byte[]> list = new ArrayList<>();
while (true) {
    list.add(new byte[1024 * 1024]); // Добавляем по 1MB
    // В итоге память заканчивается
}
// Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

Варианты OutOfMemoryError:

  • Java heap space — недостаточно памяти в heap
  • GC overhead limit exceeded — сборщик мусора потратил > 98% времени
  • PermGen space (Java 7) — недостаточно памяти для класс-метаданных
  • Metaspace (Java 8+) — переполнение Metaspace
  • Direct buffer memory — переполнение DirectByteBuffer
// Нельзя обработать OutOfMemoryError:
List<byte[]> list = new ArrayList<>();
try {
    while (true) {
        list.add(new byte[1024 * 1024]);
    }
} catch (OutOfMemoryError e) {
    // ❌ К этому моменту памяти нет - ловля неэффективна
    System.out.println("Out of memory");
    // Приложение всё равно упадёт
}

2. StackOverflowError

Что это: стек вызовов переполнен (обычно из-за бесконечной рекурсии)

// ❌ Бесконечная рекурсия
int recursiveMethod(int n) {
    return recursiveMethod(n + 1); // Вызывает себя без выхода
}

recursiveMethod(0);
// Exception in thread "main" java.lang.StackOverflowError

Почему это Error, а не Exception:

  • Стек уже заполнен — невозможно создать новый Exception
  • Это системная ошибка, а не ошибка логики
// Правильная рекурсия (с базовым случаем)
int factorial(int n) {
    if (n <= 1) return 1; // Базовый случай - выход
    return n * factorial(n - 1);
}

factorial(5); // ✓ Работает

3. NoClassDefFoundError

Что это: класс был найден при компиляции, но не найден во время выполнения

// ❌ Класс скомпилирован, но jar удалён
public class Main {
    public void test() {
        SomeClass obj = new SomeClass(); // Компилируется
    }
}

// Если SomeClass.class нет в classpath при запуске:
// Exception in thread "main" java.lang.NoClassDefFoundError: SomeClass

Отличие от ClassNotFoundException:

// ClassNotFoundException - проверяемое исключение
try {
    Class.forName("com.example.SomeClass"); // Динамическая загрузка
} catch (ClassNotFoundException e) {
    // ✓ Это Exception, можно обработать
    System.out.println("Class not found");
}

// NoClassDefFoundError - ошибка JVM
new SomeClass(); // Если класса нет - NoClassDefFoundError

4. ClassFormatError

Что это: файл .class имеет неверный формат

// ❌ Повреждённый class файл
try {
    ClassLoader.getSystemClassLoader().loadClass("BadClass");
} catch (ClassFormatError e) {
    // Неправильная структура class файла
}

5. LinkageError

Что это: ошибка при связывании (linking) классов

Подвиды:

  • UnsatisfiedLinkError — native метод не найден
  • IncompatibleClassChangeError — несовместимость класса (например, интерфейс изменился)
// UnsatisfiedLinkError
public class NativeExample {
    native void someNativeMethod(); // Реализация в C/C++
    
    public void test() {
        someNativeMethod(); // Если native библиотека не загружена
        // java.lang.UnsatisfiedLinkError: someNativeMethod
    }
}

6. AssertionError

Что это: не выполнено условие в assert

public class AssertExample {
    public static void main(String[] args) {
        int value = 5;
        assert value > 10 : "Value must be > 10"; // ❌ Условие ложно
        // Exception in thread "main" java.lang.AssertionError: Value must be > 10
    }
}

// Запуск с включением assert:
// java -ea AssertExample

Когда использовать assert:

public class Calculator {
    public int divide(int a, int b) {
        // ✓ Проверка инвариантов в private методах
        assert b != 0 : "Divisor cannot be zero";
        return a / b;
    }
}

7. ThreadDeath

Что это: поток был остановлен методом stop() (deprecated)

// ❌ Deprecated и опасно
Thread thread = new Thread(() -> {
    while (true) {
        // ...
    }
});
thread.start();
thread.stop(); // Генерирует ThreadDeath - никогда не используй!

Правильный способ остановить поток:

// ✓ Используй флаг
volatile boolean running = true;
Thread thread = new Thread(() -> {
    while (running) {
        // работа
    }
});
running = false; // Мягкая остановка

8. ExceptionInInitializerError

Что это: исключение при инициализации класса

public class BadInitializer {
    static {
        int x = 1 / 0; // ❌ Ошибка в static блоке
        // Exception in thread "main" java.lang.ExceptionInInitializerError
    }
}

Почему Error — это не Exception?

АспектErrorException
ПричинаОшибка JVM/системыОшибка приложения
ОбработкаНЕ рекомендуется ловитьМожно и нужно ловить
ВосстановлениеНевозможноВозможно
ПримерыOOM, StackOverflowIOException, NPE

Правило обработки Error

// ❌ НЕ ДЕЛАЙ ТАК
try {
    // код
} catch (Error e) {
    // Ловля Error нарушает контракт
    System.out.println("Ошибка");
}

// ❌ НЕ ДЕЛАЙ И ТАК
try {
    // код
} catch (Throwable t) {
    // Ловишь и Exception И Error
    // Это скрывает серьёзные проблемы
}

// ✅ ПРАВИЛЬНО
try {
    // код
} catch (IOException e) {
    // Ловишь только конкретные Exception
    log.error("IO failed", e);
    // Можешь что-то сделать
}

Диагностика Error

# Для OutOfMemoryError:
java -Xmx512m MyApplication
# Увеличиваем максимум памяти

# Для анализа heap dump:
jmap -dump:live,format=b,file=heap.hprof <pid>
jhat heap.hprof

# Для StackOverflowError:
java -Xss1m MyApplication
# Увеличиваем размер stack

Вывод: Error — это ошибки JVM, которые указывают на критические проблемы системы. Приложение не должно их ловить, а должно завершиться корректно. Перед запуском нужно учитывать требования к памяти и ресурсам.