Exception (виняток) – це об’єкт, який повідомляє про помилку або непередбачену ситуацію, що виникла під час виконання програми та порушила її нормальний перебіг.

Що таке обробка винятків

Exception handling (обробка винятків) – це механізм, який дозволяє вказати програмі, що робити якщо під час виконання виникла помилка або непередбачена ситуація. Наприклад, коли програма не може знайти файл (FileNotFoundException) або підключитися до бази даних (SQLException), і такі помилки не оброблені, програма зупиниться. Якщо ж використати конструкцію try-catch, програма зможе перехопити виняток, обробити його та продовжити роботу.

Різниця між Error та Exception

Error – це серйозна помилка, яка виникає під час роботи Java і зазвичай не може бути виправлена програмою. Вона вказує на збої у роботі самої віртуальної машини Java (JVM) або системного середовища, наприклад: OutOfMemoryError, StackOverflowError. Такі помилки не призначені для обробки в коді – програма не повинна намагатися їх перехоплювати за допомогою try-catch, оскільки відновлення після них зазвичай неможливе.

Exception – це виняткова ситуація, що виникає під час виконання програми та може бути оброблена в коді за допомогою конструкцій try-catch. Серед поширених прикладів – IOException (проблеми з читанням або записом файлів) та SQLException (помилки під час роботи з базами даних). Такі ситуації менш критичні, ніж Error, і зазвичай можуть бути передбачені та оброблені програмою.

Типи винятків у Java

Checked Exceptions – це тип винятків у Java, які успадковують клас Exception, але не є нащадками RuntimeException. Такі винятки називають перевіреними, тому що компілятор вимагає обов’язково обробити їх у коді через конструкцію try-catch або оголосити в сигнатурі методу за допомогою ключового слова throws. Приклади перевірених винятків: IOException, SQLException. Вони дозволяють виявляти потенційні помилки ще на етапі компіляції, що підвищує надійність програми.

Unchecked Exceptions – це винятки в Java, які успадковують клас RuntimeException. Серед них такі класи як ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException, тощо. Неперевірені винятки не вимагають обов’язкової обробки під час компіляції: компілятор не змушує використовувати конструкцію try-catch або оголошувати їх у сигнатурі методу через throws. Проте вони можуть виникати під час виконання програми, якщо не передбачити відповідні перевірки у коді.

Докладніше про Checked та Unchecked Exceptions.

Ключові слова Java при роботі з винятками

try – ключове слово, яке використовується для визначення блоку коду, в якому може виникнути виняток. Після блоку try обов’язково має йти хоча б один із блоків: catch, finally або обидва. Інакше кажучи, блок try не може існувати самостійно без супровідних блоків для обробки або завершальних дій.

catch – ключове слово, що використовується для обробки винятків, які виникли у відповідному блоці try. Блок catch завжди розташовується одразу після try і не може використовуватись самостійно. Після catch може бути блок finally, але його використання не є обов’язковим.

finally – використовується для визначення блоку коду, що виконується завжди, незалежно від того, чи виник виняток у блоці try, і чи був він оброблений у блоці catch. Блок finally гарантує виконання завершальних або необхідних дій, як наприклад закриття файлів або звільнення ресурсів.

throw – ключове слово в Java, яке дозволяє примусово згенерувати виняток у потрібному місці коду. Для цього з допомогою throw створюють об’єкт винятку – екземпляр класу, що наслідує Throwable (наприклад IllegalArgumentException, IOException, тощо). Оператор throw можна використовувати в будь-якому методі або блоці коду.

throws – використовується у сигнатурі методу для оголошення винятків, які цей метод може згенерувати під час виконання. Сам throws не створює винятки, а лише повідомляє код, що викликає метод, про можливість їх виникнення. Записується після списку параметрів методу і перед відкриваючою дужкою тіла методу.

Приклади обробки винятків у Java

Розглянемо приклади коду, що демонструють використання ключових слів Java для роботи з винятками:

1. try-catch-finally (обробка винятків):

public class Main {

    public static void main(String[] args) {
        try {
            // Код, де може виникнути помилка
            int result = 10 / 0; // ArithmeticException: / by zero
            System.out.println("Результат: " + result);
        }
        catch (ArithmeticException e) {
            // Обробка конкретного винятку
            System.out.println("Помилка: Ділення на нуль!");
        }
        finally {
            // Виконується завжди
            System.out.println("Блок finally: Цей код виконається в будь-якому випадку");
        }
    }
}

// Output:
// Помилка: Ділення на нуль!
// Блок finally: Цей код виконається в будь-якому випадку

2. throw (примусова генерація винятку):

public class Main {

    static void checkAge(int age) {
        if (age < 18) {
            // Генерація винятку вручну
            throw new IllegalArgumentException("Вік менше 18 років!");
        }
        System.out.println("Доступ дозволено");
    }

    public static void main(String[] args) {
        try {
            checkAge(15); // Виклик методу з невалідним значенням
        }
        catch (IllegalArgumentException e) {
            System.out.println("Виняток: " + e.getMessage());
        }
    }
}

// Output:
// Виняток: Вік менше 18 років!

3. throws (оголошення винятків методу):

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Main {

    // Метод оголошує, що може кинути виняток IOException
    public static void readFile(String filePath) throws IOException {
        // try-with-resources забезпечує автоматичне закриття BufferedReader
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        }
        // Автоматичне закриття reader після виходу з блоку try
    }

    public static void main(String[] args) {
        try {
            readFile("example.txt"); // Спроба прочитати файл
        } catch (IOException e) {
            System.out.println("Помилка при читанні файлу: " + e.getMessage());
        }
    }
}

// Output:
// Помилка при читанні файлу: example.txt (The system cannot find the file specified)

4. Комбінація try-catch з кількома блоками catch:

public class Main {

    public static void main(String[] args) {
        try {
            int[] numbers = new int[5];
            numbers[10] = 30; // ArrayIndexOutOfBoundsException
            System.out.println(numbers[10]);
        }
        catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Помилка індексу масиву: " + e.getMessage());
        }
        catch (Exception e) {
            System.out.println("Загальний виняток: " + e);
        }
    }
}

// Output:
// Помилка індексу масиву: Index 10 out of bounds for length 5

На що слід звернути увагу:

1. try-catch-finally:

  • try: блок для “небезпечного” коду
  • catch: перехоплює конкретний тип винятку
  • finally: виконується завжди (навіть якщо виняток не виник)

2. throw:

  • використовується для примусової генерації винятку
  • часто використовується з кастомними перевірками

3. throws:

  • вказує в сигнатурі методу винятки які він може генерувати
  • змушує код що викликає метод обробити цей виняток

4. Особливості:

  • блок try вимагає додавання блоків або catch, або finally
  • при використанні кількох блоків catch, їх слід розташовувати для обробки від більш специфічних винятків до загальних
  • finally часто використовується для звільнення ресурсів (закриття файлів, тощо)

Мітки: