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

Что такое Exception?

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

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

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

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

# Что такое Exception?

Определение

Exception (исключение) — это объект, представляющий ошибочную ситуацию или необычное событие, которое происходит во время выполнения программы и нарушает нормальный ход её работы.

В Java Exception — это класс из пакета java.lang, который наследуется от Throwable.

Иерархия Throwable

java.lang.Throwable
├── Error (критические ошибки JVM)
│   ├── OutOfMemoryError
│   ├── StackOverflowError
│   └── VirtualMachineError
└── Exception (обрабатываемые исключения)
    ├── Checked Exception (проверяемые)
    │   ├── IOException
    │   ├── SQLException
    │   └── CustomCheckedException
    └── Runtime Exception (непроверяемые)
        ├── NullPointerException
        ├── ArrayIndexOutOfBoundsException
        └── IllegalArgumentException

Checked vs Unchecked Exception

Checked Exception (проверяемые)

Проверяются компилятором. Обязательно обработать (try-catch) или объявить в сигнатуре (throws):

public class FileProcessor {
    // Вариант 1: обработать исключение
    public void readFile(String filename) {
        try {
            FileInputStream fis = new FileInputStream(filename);
            // читаем файл
        } catch (FileNotFoundException e) {
            System.err.println("File not found: " + e.getMessage());
        }
    }
    
    // Вариант 2: пробросить исключение дальше
    public String readFileContent(String filename) throws IOException {
        FileInputStream fis = new FileInputStream(filename);
        // читаем и возвращаем контент
        return "content";
    }
}

Примеры Checked Exception:

  • IOException
  • SQLException
  • ClassNotFoundException
  • InterruptedException

Unchecked Exception (непроверяемые, Runtime)

Не проверяются компилятором. Можно не обрабатывать явно (но нежелательно):

public class DataProcessor {
    public int divide(int a, int b) {
        // Компилятор не заставит обработать ArithmeticException
        return a / b; // Может выбросить ArithmeticException если b == 0
    }
    
    public String processArray(String[] items, int index) {
        // Может выбросить ArrayIndexOutOfBoundsException
        return items[index].toUpperCase();
    }
    
    public void processObject(Object obj) {
        // Может выбросить NullPointerException
        obj.toString();
    }
}

Примеры Unchecked Exception:

  • NullPointerException
  • ArrayIndexOutOfBoundsException
  • ArithmeticException
  • IllegalArgumentException
  • ClassCastException

Базовая структура Exception

try {
    // Код, который может выбросить исключение
    int result = 10 / 0;
} catch (ArithmeticException e) {
    // Обработка конкретного типа исключения
    System.err.println("Cannot divide by zero");
    e.printStackTrace(); // Вывести stack trace
} catch (Exception e) {
    // Catch более общего типа (должен быть после специфичных)
    System.err.println("Unexpected error: " + e.getMessage());
} finally {
    // Выполняется ВСЕГДА, даже если было исключение
    System.out.println("Cleanup code");
}

Типичные методы Exception

public class ExceptionMethods {
    public static void main(String[] args) {
        try {
            throw new IllegalArgumentException("Invalid age");
        } catch (IllegalArgumentException e) {
            // getMessage() - возвращает сообщение об ошибке
            System.out.println(e.getMessage()); // Invalid age
            
            // getClass().getSimpleName() - имя класса исключения
            System.out.println(e.getClass().getSimpleName()); // IllegalArgumentException
            
            // printStackTrace() - полный стек вызовов
            e.printStackTrace();
            
            // getCause() - исходная причина (если обёрнуто)
            Throwable cause = e.getCause();
            
            // getStackTrace() - массив элементов стека
            StackTraceElement[] stackTrace = e.getStackTrace();
        }
    }
}

Пример: Создание собственного Exception

// Checked exception - наследуется от Exception
public class InsufficientFundsException extends Exception {
    private double amount;
    
    public InsufficientFundsException(String message, double amount) {
        super(message);
        this.amount = amount;
    }
    
    public double getAmount() {
        return amount;
    }
}

// Unchecked exception - наследуется от RuntimeException
public class InvalidUserInputException extends RuntimeException {
    public InvalidUserInputException(String message) {
        super(message);
    }
}

public class BankAccount {
    private double balance = 100;
    
    public void withdraw(double amount) throws InsufficientFundsException {
        if (amount <= 0) {
            throw new InvalidUserInputException("Amount must be positive");
        }
        if (amount > balance) {
            throw new InsufficientFundsException("Not enough money", amount);
        }
        balance -= amount;
    }
    
    public static void main(String[] args) {
        BankAccount account = new BankAccount();
        
        // Обработка checked exception
        try {
            account.withdraw(150);
        } catch (InsufficientFundsException e) {
            System.out.println("Error: " + e.getMessage());
            System.out.println("Requested: " + e.getAmount());
        }
        
        // Unchecked exception может быть не обработан
        account.withdraw(-10); // Выбросит InvalidUserInputException
    }
}

Try-with-resources (Java 7+)

Автоматическое закрытие ресурсов:

public class ResourceManagement {
    public void readFile(String filename) {
        // Автоматически закроется после try блока
        try (FileInputStream fis = new FileInputStream(filename)) {
            // Читаем файл
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public void multipleResources() {
        try (
            FileInputStream fis = new FileInputStream("input.txt");
            FileOutputStream fos = new FileOutputStream("output.txt")
        ) {
            // Работа с обоими ресурсами
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

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

  1. Не глушите исключения:
// Плохо
try {
    risky();
} catch (Exception e) {
    // Молчаливо игнорируем
}

// Хорошо
try {
    risky();
} catch (IOException e) {
    logger.error("Failed to process", e);
    throw new RuntimeException("Processing failed", e);
}
  1. Ловите специфичные исключения:
// Плохо
try { ... } catch (Exception e) { ... }

// Хорошо
try { ... } catch (IOException e) { ... }
  1. Используйте finally или try-with-resources для очистки ресурсов

  2. Не используйте Exception для управления потоком:

// Плохо - перехватываем для нормального потока
while (true) {
    try {
        item = queue.remove(); // Выбросит NoSuchElementException если пусто
    } catch (NoSuchElementException e) {
        break;
    }
}

// Хорошо
while (!queue.isEmpty()) {
    item = queue.poll();
}

Заключение

Exception в Java — это механизм обработки ошибок, который позволяет:

  • Разделить обработку ошибок от основной логики
  • Пробросить ошибку на уровень, который её может обработать
  • Гарантировать выполнение cleanup кода (finally)
  • Создавать иерархии собственных исключений для better error handling
Что такое Exception? | PrepBro