JavaRush /Java блог /Random UA /Винятки та їх обробка
articles
15 рівень

Винятки та їх обробка

Стаття з групи Random UA
Винятками чи винятковими ситуаціями (станами) називаються помилки, що виникли у програмі під час її роботи. Усі винятки Java є об'єктами. Тому можуть породжуватися як автоматично у разі виняткової ситуації, а й створюватися самим розробником. Ієрархія класів винятків: Винятки та їх обробка - 1Винятки поділяються на кілька класів, але вони мають загального предка - клас Throwable. Його нащадками є Exceptionпідкласи Error. Винятки ( Exceptions) є результатом проблем у програмі, які в принципі вирішуються та передбачувані. Наприклад, стався поділ на нуль у цілих числах. Помилки (Errors) являють собою серйозніші проблеми, які, згідно специфікації Java, не слід намагатися обробляти у власній програмі, оскільки вони пов'язані з проблемами рівня JVM. Наприклад, винятки такого роду виникають, якщо закінчилася пам'ять, доступна віртуальній машині. Програма додаткову пам'ять все одно не зможе забезпечити для JVM. У Java всі винятки поділяються на три типи: контрольовані винятки ( checked) і неконтрольовані винятки ( unchecked), до яких належать помилки ( Errors) та виключення часу виконання ( RuntimeExceptions, нащадок класу Exception). Контрольовані винятки є помилками, які можна і потрібно обробляти в програмі, до цього типу відносяться всі нащадки класу Exception(але неRuntimeException). Обробка виключення може бути здійснена за допомогою операторів try…catchабо передана зовнішній частині програми. Наприклад, метод може передавати виключення, що виникли в ньому, вище за ієрархією викликів, сам його не обробляючи. Неконтрольовані винятки не вимагають обов'язкової обробки, проте, за бажання, можна обробляти винятки класу RuntimeException. Відкомпілюємо та запустимо таку програму:
class Main {
     public static void main(String[] args) {
         int a = 4;
         System.out.println(a/0);
     }
}
У момент запуску на консоль буде виведено таке повідомлення:
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at Main.main(Main.java:4)
З повідомлення видно клас виключення, що сталося - ArithmeticException. Цей виняток можна обробити:
class Main {
     public static void main(String[] args) {
         int a = 4;
         try {
              System.out.println(a/0);
         } catch (ArithmeticException e) {
              System.out.println("Произошла недопустимая арифметическая операция");
         }
     }
}
Тепер замість стандартного повідомлення про помилку буде виконуватися блок catch, параметром якого є об'єкт e відповідного виключення класу (самому об'єкту можна давати будь-яке ім'я, воно знадобиться в тому випадку, якщо ми побажаємо знову примусово викинути цей виняток, наприклад, щоб він був перевірений якимось ще обробником). У блок tryпри цьому поміщається фрагмент програми, де потенційно може виникнути виняток. Одному tryможе відповідати відразу кілька блоків catch із різними класами винятків.
import java.util.Scanner;
class Main {
    public static void main(String[] args) {
     int[] m = {-1,0,1};
        Scanner sc = new Scanner(System.in);
        try {
            int a = sc.nextInt();
            m[a] = 4/a;
            System.out.println(m[a]);
        } catch (ArithmeticException e) {
            System.out.println("Произошла недопустимая арифметическая операция");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Обращение по недопустимому индексу массива");
        }
    }
}
Якщо запустивши представлену програму, користувач введеться з клавіатури 1 або 2, програма відпрацює без створення будь-яких винятків. Якщо користувач введе 0, то виникне виняток класу ArithmeticExceptionі воно буде оброблено першим блоком catch. Якщо користувач введе 3, то виникне виняток класу ArrayIndexOutOfBoundsException(вихід за межі масиву), і воно буде оброблено другим блоком catch. Якщо користувач введе неціле число, наприклад, 3.14, то виникне виняток класу InputMismatchException(невідповідність типу значення, що вводиться), і воно буде викинуто у форматі стандартної помилки, оскільки його ми ніяк не обробляли. Проте можна додати обробник для класуException, оскільки цей клас батьківський всім інших контрольованих винятків, він перехоплюватиме будь-які їх (зокрема, і InputMismatchException).
import java.util.Scanner;
class Main {
    public static void main(String[] args) {
        int[] m = {-1,0,1};
        int a = 1;
        Scanner sc = new Scanner(System.in);
        try {
            a = sc.nextInt();
            m[a-1] = 4/a;
            System.out.println(m[a]);
        } catch (ArithmeticException e) {
            System.out.println("Произошла недопустимая арифметическая операция");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Обращение по недопустимому индексу массива");
        } catch (Exception e) {
            System.out.println("Произошло ещё якое-то исключение");
        }
    }
}
Оскільки винятки побудовані на ієрархії класів і підкласів, спочатку треба намагатися обробити більш приватні винятки і лише потім більш загальні. Тобто поставивши першим (а не третім) блок з обробкою виключення класу Exception, ми б ніколи не побачабо жодних повідомлень про помилку, окрім «Сталося ще якесь виключення» (всі винятки перехопабося б відразу цим блоком і не доходабо до решти). Необов'язковим додаванням до блоків try…catchможе бути блок finally. Вміщені в нього команди виконуватимуться у будь-якому випадку, незалежно від того, чи відбулося виключення чи ні. При тому, що при виникненні необробленого виключення частина програми, що залишилася після генерації цього виключення, — не виконується. Наприклад, якщо виняток виник у процесі якихось тривалих обчислень, у блоціfinallyВи можете показати або зберегти проміжні результати. Посилання на першоджерело: Винятки та їх обробка
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ