1. Клас Throwable: корінь усіх винятків
Зараз докладно розглянемо, як побудована система винятків у Java: що таке Throwable, чим відрізняються Exception і Error, а також що означають «перевірюваний» і «неперевірюваний» винятки. Це фундамент для грамотної обробки помилок у ваших програмах.
У Java усі винятки й помилки — це обʼєкти, які наслідуються від класу java.lang.Throwable.
Throwable — кореневий клас ієрархії винятків у Java.
Схематично:
Throwable
├── Exception
└── Error
Throwable — базовий клас для всього, що може бути «викинуте» (throw) і «спіймане» (catch) у Java. Його не можна використовувати безпосередньо — він слугує основою для конкретніших типів помилок.
Exception — для «нормальних» помилок
Exception — базовий клас для всіх винятків, що можуть виникнути у програмі й які можна й потрібно обробляти. Це «робочі» помилки: проблеми з файлами, мережею, введенням-виведенням, помилками користувача тощо. Більшість ваших try-catch працюватиме саме з нащадками Exception.
Приклади:
- IOException — помилка під час роботи з файлами або мережею.
- SQLException — помилка під час роботи з базою даних.
- FileNotFoundException — файл не знайдено.
Error — для фатальних помилок JVM
Error — базовий клас для помилок, які відбуваються на рівні віртуальної машини Java (JVM). Зазвичай це критичні збої, які програма не може і не повинна обробляти. Якщо виник Error — швидше за все, застосунок не зможе продовжити роботу.
Приклади:
- OutOfMemoryError — закінчилася памʼять.
- StackOverflowError — переповнення стеку (наприклад, через нескінченну рекурсію).
- NoClassDefFoundError — не знайдено потрібний клас.
Важливо:
Ловити й обробляти Error — майже завжди погана ідея. Це не помилки вашої програми, а збої середовища виконання.
2. Checked vs Unchecked: що це означає?
У Java усі винятки поділяються на дві великі групи:
Перевірювані (Checked) винятки
Що це? Винятки, які компілятор змушує обробити або явно передати далі.
Коли виникають? Зазвичай повʼязані із зовнішніми ресурсами: файлами, мережею, базами даних, введенням користувача.
Як обробляти? Потрібно або обернути код у try-catch, або додати throws у сигнатуру методу.
Приклади: IOException, SQLException, FileNotFoundException
Приклад:
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path); // може викинути IOException
// ...
}
Якщо не обробити або не передати далі — програма не скомпілюється!
Неперевірювані (Unchecked) винятки
Що це? Винятки, які не потребують обовʼязкової обробки компілятором.
Коли виникають? Зазвичай це помилки в логіці програми: ділення на нуль, вихід за межі масиву, звернення до null.
Як обробляти? Можна ловити, але не обовʼязково. Краще запобігати таким помилкам за допомогою перевірок.
Де в ієрархії? Усі наслідуються від RuntimeException.
Приклади: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException, ArithmeticException
Приклад:
int[] arr = {1, 2, 3};
System.out.println(arr[10]); // ArrayIndexOutOfBoundsException
Компілятор не вимагає обробки, але програма «впаде» у разі помилки.
3. Уся ієрархія на одній картинці
graph TD
Throwable --> Error
Throwable --> Exception
Exception --> RuntimeException
Exception --> CheckedExceptions["(інші Checked Exceptions)"]
Error --> OutOfMemoryError
Error --> StackOverflowError
RuntimeException --> NullPointerException
RuntimeException --> IndexOutOfBoundsException
RuntimeException --> IllegalArgumentException
%% Стилі
style Throwable fill:#ffa64d,color:#000
style Exception fill:#ffa64d,color:#000
style CheckedExceptions fill:#ffa64d,color:#000
style Error fill:#ff4d4d,color:#fff
style OutOfMemoryError fill:#ff4d4d,color:#fff
style StackOverflowError fill:#ff4d4d,color:#fff
style RuntimeException fill:#4dff88,color:#000
style NullPointerException fill:#4dff88,color:#000
style IndexOutOfBoundsException fill:#4dff88,color:#000
style IllegalArgumentException fill:#4dff88,color:#000
Таблиця: основні відмінності
| Група | Батьківський клас | Потребує обробки? | Приклади |
|---|---|---|---|
| Checked Exception | |
Так | |
| Unchecked | |
Ні | |
| Error | |
Ні | |
4. Як це виглядає в коді?
Checked Exception: приклад із файлами
import java.io.*;
public class FileDemo {
public static void main(String[] args) {
try {
FileReader reader = new FileReader("nofile.txt"); // FileNotFoundException (checked)
int data = reader.read();
System.out.println(data);
reader.close();
} catch (IOException e) {
System.out.println("Помилка під час роботи з файлом: " + e.getMessage());
}
}
}
Компілятор змусить обробити IOException!
Unchecked Exception: приклад із діленням на нуль
public class ExceptionDemo {
public static void main(String[] args) {
int a = 10;
int b = 0;
int c = a / b; // ArithmeticException (unchecked)
System.out.println("Результат: " + c);
}
}
Компілятор не вимагає обробки, але програма «впаде».
5. Навіщо потрібна ієрархія винятків?
- Гнучкість обробки: можна ловити як конкретні помилки (FileNotFoundException), так і цілі групи (IOException або Exception).
- Повторне використання коду: можна централізовано обробляти помилки одного типу.
- Чистота коду: основна логіка не засмічується перевірками на кожну дрібницю.
Приклад:
try {
// небезпечний код
} catch (FileNotFoundException e) {
System.out.println("Файл не знайдено!");
} catch (IOException e) {
System.out.println("Помилка введення-виведення!");
} catch (Exception e) {
System.out.println("Щось пішло не так: " + e.getMessage());
}
6. Типові помилки під час роботи з винятками
Помилка № 1: Ігнорування винятків. Писати catch (Exception e) {} — погано! Ви втрачаєте інформацію про причину помилки.
Помилка № 2: Ловимо занадто багато. catch (Exception e) ловить усе підряд, навіть те, чого не очікували. Краще ловити лише ті винятки, які вмієте обробляти.
Помилка № 3: Ловимо помилки (Error). Не варто ловити Error, якщо ви не пишете низькорівневий код. Це проблеми JVM, а не вашої програми.
Помилка № 4: Не розрізняємо checked і unchecked. Не всі винятки однакові! Checked потребують обробки (Exception), unchecked — ні (RuntimeException та нащадки).
Помилка № 5: Не додаємо інформації до винятків. Якщо створюєте свої винятки — завжди додавайте інформативне повідомлення.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ