Винятки в Java — пояснення та приклади
Що таке виняток у Java (Java Exception)?
Виняток – це небажана ситуація, що виникає під час виконання програми та порушує нормальний перебіг її роботи.
Така ситуація може виникнути, наприклад, через спробу читання з файлу, якого не існує, ділення на нуль, збій пристрою тощо. Виняток можна перехопити, щоб вжити відповідних заходів.
Наведемо приклад коду, у якому виникає виняток.
class ExceptionTest{ // Метод приймає два цілих числа // та повертає результат поділу // першого на друге static float divide(int x, int y){ float result = x / y; return result; } public static void main(String args[]){ // Ця стрічка буде виконана System.out.println(divide(4, 2)); // Ця теж System.out.println(divide(0, 2)); // Ця викине виняток System.out.println(divide(4, 0)); } }
Якщо його запустити, отримаємо наступний результат:
2.0 0.0 Exception in thread "main" java.lang.ArithmeticException: / by zero at ExceptionTest.divide(ExceptionTest.java:6) at ExceptionTest.main(ExceptionTest.java:16)
Виводяться два результати ділення та повідомлення про виняток. У цьому повідомленні вказано таку інформацію:
- тип винятку (ArithmeticException);
- який саме виняток виник (розподіл на нуль);
- стек виконання: методи та рядки, у яких виник виняток.
Оператори try, catch, finally, throw, throws: обробка винятків та приклади використання
Для перехоплення виняткових ситуацій створюється об’єкт винятку, що передається середовищу виконання. Він містить інформацію про помилку, зокрема її тип та стан програми на момент виникнення помилки. Створення об’єкта винятку та його передача середовищу виконання називається викиданням виняткової ситуації.
try-catch
Для перехоплення винятку використовується конструкція try–catch. Код, який потрібно перевірити на виняток, розміщено в блоці try, а код, що обробляє виняток, – у блоці catch.
Додамо ці блоки до наведеного вище блоку коду і доповнимо його парою змінних для наочності.
class ExceptionTest{ // Метод принимает два целых числа // и возвращает результат деления // первого на второе static float divide(int x, int y){ float result = x / y; return result; } public static void main(String args[]){ int x = 4; int y = 2; try { // Эта строка будет выполнена System.out.println(divide(x, y)); x = 0; // Эта тоже System.out.println(divide(x, y)); x = 4; y = 0; // Эта выбросит исключение System.out.println(divide(x, y)); } catch (ArithmeticException e) { System.out.println("Ошибка при делении " + x + " на " + y); } } }
Отримаємо більш зручний для читання результат:
2.0
0.0
Помилка ділення 4 на 0
finally
Блок finally виконується після try-catch незалежно від того, чи виник виняток. Це необов’язковий блок, але якщо немає блоку catch, то блок finally необхідний.
У цьому блоці можна, наприклад, закрити файл, який відкрито в блоці try, як у наведеному нижче коді.
import java.io.FileWriter; import java.io.IOException; public class FinallyTest { public static void main(String[] args) { FileWriter writer = null; try { writer = new FileWriter("out.txt"); writer.write("Writing to the file!"); System.out.println("Файл записаний вдало."); } catch (IOException e) { System.out.println("Помилка запису у файл."); e.printStackTrace(); } finally { if ( writer != null ){ try{ writer.close(); } catch (IOException e) { System. out.println("Помилка закриття файла."); e.printStackTrace(); } } } } }
throw
У деяких випадках потрібно викинути виняток самостійно. Це робиться за допомогою ключового слова throw .
У цьому прикладі метод PrintMe викидає виняток, якщо його аргумент дорівнює null.
import java.util.LinkedList; public class ThrowTest { public static void main(String[] args) { LinkedList<String> fruits = new LinkedList<String>(); fruits.add("apple"); fruits.add("banana"); fruits.add("orange"); fruits.add("mango"); // Печатает список ThrowTest.PrintMe(fruits); // Выбрасывает исключение ThrowTest.PrintMe(null); } public static void PrintMe(LinkedList<String> fruits){ if (fruits == null){ throw new NullPointerException("Аргумент не инициализирован"); } System.out.println(fruits); } }
Ієрархія винятків Java
Винятки в Java поділяються на дві основні категорії: вбудовані та користувацькі.
Вбудовані винятки
Вбудовані винятки – це винятки, які визначено в Java.
Коли виникає вбудований виняток, віртуальна машина Java (JVM) створює об’єкт, що належить класу вбудованого винятку. Усі винятки походять від класу java.lang.Throwable, але їх визначено в кількох пакетах.
Клас Throwable походить безпосередньо від класу Object і є кореневим класом дерева класів винятків. Від нього походять два підкласи: Error та Exception. Помилки й винятки, які зустрічаються в програмах Java, є об’єктами цих класів.
За допомогою класу Throwable можна створювати власні винятки.
Клас Error є надкласом всім класів помилок часу виконання. Він завершує виконання програми, якщо відбувається помилка, пов’язана із системою або ресурсами (JVM).
Помилка зазвичай є незвичайною проблемою, після якої складно здійснити відновлення. Вони відбуваються не з вини програміста, а через неналежну роботу системи або виділення ресурсів.
Приклади помилок: AssertionError, LinkageError, OutOfMmeoryError, StackOverFlowError, VirtualMachineError.
Клас Exception представляє помилки, які спричинено програмою чи зовнішніми чинниками. Це надклас для всіх класів винятків.
Для цього класу існує два конструктори:
- public Exception() (за замовчуванням)
- public Exception(String message) (приймає рядкове повідомлення як аргумент)
Ці конструктори успадковуються всіма підкласами винятків. Сам собою клас Exception не надає своїх методів. Він успадковує методи класу Throwable.
Вбудовані винятки поділяються на дві групи: перевірювані (checked) та неперевірювані (unchecked).
Перевірювані винятки Java
Переваірювані винятки перевіряються компілятором Java під час компіляції і не є підкласами RuntimeException (винятку часу виконання).
Якщо метод викидає перевірюваний виняток, то цей виняток необхідно обробити або в цьому самому методі, або передати методу, який його викликав.
Перевірювані винятки обробляються або в блоці try-catch, або в оголошенні методу з ключовим словом throws. Якщо виняток не опрацьовано, відбувається помилка компіляції.
Перевіреними винятками є всі винятки, крім RuntimeException, Error та його підкласів.
Приклади винятків, що перевіряються: ClassNotFoundException, IOException, SQLException, IllegalAccessException, FileNotFoundException.
Неперевірювані винятки (винятки часу виконання) в Java
Неперевірювані винятки в Java – це винятки, які перевіряються JVM, а не компілятором Java. Вони виникають під час виконання програми.
Усі підкласи RuntimeException називаються неперевіреними винятками або винятками часу виконання в Java.
Можна написати програму на Java й скомпілювати її, але ми не побачимо неперевірених виключень і помилок, поки не запустимо цю програму.
Компілятор Java не перевіряє винятки часу виконання під час компіляції, незалежно від того, чи обробляє їх програма.
Якщо в методі виникає виняток часу виконання, а програміст не обробляє його, JVM припиняє виконання програми та не виконує остаток коду.
Приклади неперевірюваних винятків: ArithmeticException, ArrayIndexOutOfBoundsException, ClassCastException, NegativeArraySizeException, NullPointerException.
У Java визначено багато вбудованих винятків. Нижче наведено описи деяких з них.
Виняток | Опис |
ArithmeticException | Викидається, коли виникає виняткова арифметична ситуація. |
ArrayIndexOutOfBoundsException | Викидається під час спроби звернутися до масиву за недійсним індексом. |
ArrayStoreException | Викидається під час спроби зберегти об’єкт невідповідного типу в масиві об’єктів. |
ClassCastException | Викидається, коли код здійснює спробу привести тип об’єкта до підкласу, екземпляром якого він не є. |
ClassNotFoundException | Викидається, коли програма намагається завантажити клас за його ім’ям у рядковому поданні з використанням методу forName у класі Class. |
CloneNotSupportedException | Викидається, коли для клонування об’єкта певного класу викликано метод clone, але клас цього об’єкта не реалізує інтерфейс Cloneable. |
EnumConstantNotPresentException | Викидається, коли програма намагається звернутися до константи з переліку на ім’я, але тип цього переліку не містить константу з зазначеним ім’ям. |
Виняток | Клас Exception та його підкласи є підкласами Throwable та вказують на ситуації, які можуть бути перехоплені програмою. |
IllegalAccessException | Викидається, коли програма намагається застосувати рефлексію, щоб створити примірник (відмінний від масиву), призначити полю значення або отримати значення поля, викликати метод, але поточний метод не має доступу до визначення зазначеного класу, поля, методу чи конструктора. |
IllegalArgumentException | Викидається, коли методу передано неприпустимий чи неприйнятний аргумент. |
IllegalMonitorStateException | Викидається, коли нитка намагається очікувати на монітор об’єкта або надіслати сповіщення іншим ниткам, які чекають на монітор об’єкта, але вказаний монітор не належить їй. |
IllegalStateException | Викидається, коли метод викликано в неприпустимий або неприйнятний час. |
IllegalThreadStateException | Викидається, коли нитка знаходиться в неприйнятному стані для виконання цієї операції. |
IndexOutOfBoundsException | Викидається, коли індекс певного типу (наприклад, для масиву, рядка або вектора) знаходиться поза допустимим діапазоном. |
InstantiationException | Викидається, коли програма намагається створити екземпляр класу з використанням методу newInstance класу Class, але створити екземпляр зазначеного класу неможливо. |
InterruptedException | Викидається, коли нитка перебуває в стані очікування, сну або зайнята іншими діями, але її роботу перервано перед виконанням дії чи після її виконання. |
Виняток NegativeArraySize | Викидається, коли програма робить спробу створити масив негативного розміру. |
NoSuchFieldException | Викидається, коли в класі немає поля з зазначеним ім’ям. |
NoSuchMethodException | Викидається, коли неможливо знайти вказаний метод. |
NullPointerException | Викидається, коли програма намагається використовувати значення null, але потрібно вказати об’єкт. |
NumberFormatException | Викидається, коли програма намагається перетворити рядок на один із числових типів, але рядок має неприпустимий формат. |
RuntimeException | Це батьківський клас для тих винятків, які можуть бути викинуті за нормальної роботи віртуальної машини Java. |
SecurityException | Викидається менеджером безпеки у випадку порушення безпеки. |
StringIndexOutOfBoundsException | Викидається методами класу String під час спроби використати негативний індекс або індекс, що перевищує розмір рядка. |
TypeNotPresentException | Викидається, коли програма намагається отримати доступ до типу з зазначенням його імені у вигляді рядка, але не вдається знайти визначення типу зі вказаним ім’ям. |
UnsupportedOperationException | Викидається, коли запитана операція не підтримується. |
Користувацькі винятки
Користувацькі винятки створюються користувачами або програмістами відповідно до їх власних потреб. Їх створюють розширенням класу Exception.
Прикладом винятку може бути ситуація, коли користувач намагається відкрити банківський рахунок, але не досяг віку 18 років. У такому разі може бути видано повідомлення про те, що потрібно відкрити рахунок із кимось із батьків.
Щоб використовувати користувацький виняток, потрібно виконати наступні дії.
- Визначити клас, який розширює клас Exception.
- Визначити конструктор. Якщо не потрібно зберігати відомості про виняток, визначається стандартний конструктор. Якщо потрібно зберегти інформацію про виняток як рядок, визначається конструктор з параметром.
- Створити об’єкт користувацького винятку й викинути його за допомогою ключового слова throw.
Приклад винятку з конструктором за замовчуванням:
class MyException extends Exception{ // Конструктор по умолчанию MyException(){} } class Main{ public static void main(String[] args){ try{ MyException e = new MyException(); throw e; } catch(MyException ex){ System.out.println("Перехоплено користувацьке виключення"); } } }
Цей код виведе наступний текст: ” Перехоплено виняток користувача”.
Приклад виключення з параметром конструктора:
class MyException extends Exception{ MyException(String msg){ super(msg); } } class Main{ public static void main(String[] args){ try{ MyException e = new MyException("Перехоплено користувацьке виключення з інформацією"); throw e; } catch(MyException ex){ System.out.println(ex.getMessage()); } } }
Буде виведено такий текст: “Перехоплено виняток користувача з інформацією”
Висновок
Винятки Java дозволяють зазначити шляхи обходу проблем і виправлення їх наслідків. З їхньою допомогою можна помістити логіку обробки виняткових ситуацій в окремі блоки коду (catch), залишивши основну логіку в блоці try, а логіку завершальних дій з обробки винятку – у блоці finally. Винятки можуть бути оброблені в методах, де вони виникають, або передані далі за допомогою ключових throw та throws.
Java надає великий набір вбудованих винятків, а також дає програмісту гнучкість, дозволяючи створювати власні винятки відповідно до потреб програми.
Favbet Tech – це ІТ-компанія зі 100% украінською ДНК, що створює досконалі сервіси для iGaming і Betting з використанням передових технологіи та надає доступ до них. Favbet Tech розробляє інноваційне програмне забезпечення через складну багатокомпонентну платформу, яка здатна витримувати величезні навантаження та створювати унікальний досвід для гравців.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: