Обработка исключений, try... catch

import java.io.*;
import java.sql.SQLException;
import java.util.Scanner;

public class ExceptionHandlingDemo {

    // 1. Базовая обработка исключений
    public static void basicTryCatch() {
        System.out.println("=== Базовая обработка исключений ===");

        try {
            // Код, который может вызвать исключение
            int result = 10 / 0;
            System.out.println("Этот код не выполнится");
        } catch (ArithmeticException e) {
            System.out.println("Поймано арифметическое исключение: " + e.getMessage());
            // Получение стека вызовов
            e.printStackTrace();
        }
        System.out.println("Программа продолжает работу\n");
    }

    // 2. Множественные блоки catch
    public static void multipleCatch() {
        System.out.println("=== Множественные блоки catch ===");

        try {
            Scanner scanner = new Scanner(new File("несуществующий.txt"));
            int number = Integer.parseInt(scanner.nextLine());
            int result = 10 / number;
        } catch (FileNotFoundException e) {
            System.out.println("Файл не найден: " + e.getMessage());
        } catch (NumberFormatException e) {
            System.out.println("Ошибка преобразования числа: " + e.getMessage());
        } catch (ArithmeticException e) {
            System.out.println("Арифметическая ошибка: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("Общее исключение: " + e.getMessage());
        }
        System.out.println();
    }

    // 3. Multi-catch (с Java 7)
    public static void multiCatch() {
        System.out.println("=== Multi-catch обработка ===");

        try {
            String str = null;
            str.length();
        } catch (NullPointerException | IllegalArgumentException e) {
            System.out.println("Поймано одно из исключений: " + e.getClass().getSimpleName());
        }
        System.out.println();
    }

    // 4. Try-with-resources (с Java 7)
    public static void tryWithResources() {
        System.out.println("=== Try-with-resources ===");

        // Ресурсы автоматически закрываются после использования
        try (FileReader fr = new FileReader("test.txt");
             BufferedReader br = new BufferedReader(fr)) {

            String line = br.readLine();
            System.out.println(line);

        } catch (IOException e) {
            System.out.println("Ошибка ввода-вывода: " + e.getMessage());
        }
        System.out.println();
    }

    // 5. Finally блок
    public static void tryWithFinally() {
        System.out.println("=== Try с finally блоком ===");

        FileInputStream fis = null;
        try {
            fis = new FileInputStream("test.txt");
            // Работа с файлом
        } catch (IOException e) {
            System.out.println("Ошибка при работе с файлом: " + e.getMessage());
        } finally {
            System.out.println("Блок finally всегда выполняется");
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    System.out.println("Ошибка при закрытии файла");
                }
            }
        }
        System.out.println();
    }

    // 6. Вложенные try-catch блоки
    public static void nestedTryCatch() {
        System.out.println("=== Вложенные try-catch блоки ===");

        try {
            try {
                int[] arr = new int[5];
                arr[10] = 50; // Вызовет ArrayIndexOutOfBoundsException
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("Внутренний catch: " + e.getMessage());
                throw new RuntimeException("Переброс исключения", e);
            }
        } catch (RuntimeException e) {
            System.out.println("Внешний catch: " + e.getMessage());
            System.out.println("Причина: " + e.getCause().getMessage());
        }
        System.out.println();
    }

    // 7. Пример обработки checked исключений
    public static void checkedExceptions() throws SQLException {
        System.out.println("=== Обработка checked исключений ===");

        try {
            throwCheckedException();
        } catch (IOException e) {
            System.out.println("Обработка IOException: " + e.getMessage());
            // Пример переброса другого исключения
            throw new SQLException("Ошибка БД", e);
        }
    }

    private static void throwCheckedException() throws IOException {
        throw new IOException("Проверяемое исключение");
    }

    // 8. Пример создания и использования пользовательского исключения
    static class CustomException extends Exception {
        private int errorCode;

        public CustomException(String message, int errorCode) {
            super(message);
            this.errorCode = errorCode;
        }

        public int getErrorCode() {
            return errorCode;
        }
    }

    public static void handleCustomException() {
        System.out.println("=== Пользовательские исключения ===");

        try {
            throw new CustomException("Пользовательская ошибка", 500);
        } catch (CustomException e) {
            System.out.println("Сообщение: " + e.getMessage());
            System.out.println("Код ошибки: " + e.getErrorCode());
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // Демонстрация всех видов обработки исключений
        basicTryCatch();
        multipleCatch();
        multiCatch();
        tryWithResources();
        tryWithFinally();
        nestedTryCatch();

        try {
            checkedExceptions();
        } catch (SQLException e) {
            System.out.println("Основное исключение: " + e.getMessage());
            System.out.println("Причина: " + e.getCause().getMessage());
        }

        handleCustomException();
    }
}

Давайте подробно разберем все аспекты обработки исключений:

  1. Базовая структура try-catch:
try {
    // Код, который может вызвать исключение
} catch (ТипИсключения e) {
    // Обработка исключения
}
  1. Ключевые особенности:
  2. Try блок должен содержать код, который может вызвать исключение
  3. Catch блок определяет тип перехватываемого исключения
  4. Можно использовать несколько catch блоков
  5. Порядок catch блоков важен (от более специфичных к более общим)

  6. Варианты использования:

  7. try-catch: базовая обработка исключений
  8. try-catch-finally: гарантированное выполнение кода
  9. try-with-resources: автоматическое освобождение ресурсов
  10. multi-catch: обработка нескольких исключений одним блоком

  11. Finally блок:

  12. Выполняется всегда, независимо от наличия исключения
  13. Используется для освобождения ресурсов
  14. Выполняется даже при return в try или catch

  15. Try-with-resources:

  16. Автоматически закрывает ресурсы, реализующие AutoCloseable
  17. Более безопасен, чем традиционный try-finally
  18. Ресурсы закрываются в обратном порядке их объявления

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

  20. Можно получить информацию об исключении (getMessage(), getStackTrace())
  21. Можно создавать цепочки исключений (getCause())
  22. Можно перебрасывать исключения (throw)
  23. Можно преобразовывать один тип исключения в другой

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

  25. Не игнорируйте исключения (пустой catch блок)
  26. Освобождайте ресурсы в finally или используйте try-with-resources
  27. Логируйте исключения с контекстом
  28. Создавайте специфичные исключения для бизнес-логики
  29. Используйте multi-catch для сокращения дублирования кода

  30. Специальные случаи:

  31. Вложенные try-catch блоки
  32. Переброс исключений
  33. Создание собственных исключений
  34. Обработка нескольких исключений одним блоком

  35. Обработка checked и unchecked исключений:

  36. Checked исключения требуют явной обработки или объявления в throws
  37. Unchecked исключения не требуют явной обработки
  38. Error обычно не обрабатываются в программе

Хотите, чтобы я подробнее раскрыл какой-то аспект обработки исключений или привел дополнительные примеры?