1. Винятки

Нарешті програмісти здогадалися регламентувати та автоматизувати обробку помилок. Сталося це, коли винайшли винятки. Зараз за допомогою механізму винятків у світі обробляється 80% нестандартних ситуацій.
Якщо винятки вигадав якийсь учений, то, скоріш за все, він захистив на цьому докторську дисертацію. Якщо ж вигадав програміст, то він, можливо, отримав дружнє поплескування по плечу від колег: «Наче норм, бро».
Коли у Java-програмі виникає помилка, наприклад, ділення на 0, відбуваються такі чудові речі:
Крок перший
Створюється спеціальний об'єкт-виняток, у якому міститься інформація про помилку, що сталася.
Усе в Java є об'єктом, і винятки — не виняток 🙂 Об'єкти-винятки мають свої класи, і вся їхня відмінність від звичайних класів у тому, що вони успадковані від класу Throwable.
Крок другий
Об'єкт-виняток «викидається». Не дуже вдале визначення. «Викидання винятку» по суті більше схоже на включення пожежної сигналізації або сповіщення «бойова тривога».
Коли в систему «викинуто виняток», нормальний режим роботи програми припиняється, і починається «робота за аварійним протоколом».
Крок третій
Поточний метод, у якому виник (викинуто) виняток, негайно завершується. Виняток передається у викликаючий метод, який також негайно завершується. І так по ланцюжку, поки не завершиться метод main. Разом із завершенням методу main завершується і програма.
Приклад:
| Код | Вивід на екран |
|---|---|
|
|
На 20-й стрічці виникла помилка — ділення на 0. Java-машина тут же створила виняток — об'єкт класу ArithmeticException і «викинула» його в систему.
Метод поділимо() відразу завершився, тому на екран не вивелась стрічка Нічого страшного не сталося: 0. Програма повернулася в метод кінецьСвіту(), і ситуація повторилась: у системі є виняток, а значить, метод кінецьСвіту() також аварійно завершується. Потім завершується метод main, і виконання програми припиняється.
А в чому ж сенс роботи таких винятків? А в тому, що у вашій програмі можна перехоплювати винятки певного типу і написати свою логіку обробки аварійних ситуацій.
2. Перехоплення винятків try-catch
У Java є механізм перехоплення винятків, який дозволяє припинити аварійне завершення методів. Виглядає він ось так:
try
{
код, де може виникнути помилка
}
catch(ТипВинятку ім'я)
{
код обробки винятку
}
Ця конструкція називається блок try-catch.
Код, в якому можуть виникнути винятки, обгортається у фігурні дужки, перед якими пишеться слово try (спробувати).
Після фігурних дужок пишеться ключове слово catch, всередині круглих дужок оголошується змінна типу-винятку. Далі йдуть фігурні дужки, всередині яких пишеться код, який потрібно виконати, якщо виникне виняток зазначеного типу.
Якщо під час виконання «основного коду» винятків не виникло, код всередині блоку catch виконуватися не буде. Якщо ж виняток виник, блок catch виконається (за умови, що тип виниклого винятку збігається з типом змінної у круглих дужках).
Приклад:
| Код | Вивід на екран |
|---|---|
|
|
3. Кілька блоків catch

Теоретично всередині блоку коду можуть виникати дуже різні виключення. Деякі ви захочете обробити одним способом, інші — іншим, треті взагалі вирішите не обробляти.
Розробники Java вирішили допомогти вам і дозволили писати після блоку try не один блок catch, а кілька.
try
{
код, де може виникнути помилка
}
catch(ТипВиключення1 ім'я1)
{
код обробки виключення1
}
catch(ТипВиключення2 ім'я2)
{
код обробки виключення2
}
catch(ТипВиключення3 ім'я3)
{
код обробки виключення3
}
Приклад:
| Код | Вивід на екран |
|---|---|
|
|
4. Порядок блоків catch
Виняток, що виник у блоці try, може бути перехоплений лише одним блоком catch. Не може бути ситуації, коли при обробці винятку виконується код із кількох блоків catch.
Однак порядок блоків має значення.
Може бути ситуація, коли виняток перехоплено кількома блоками. У цьому випадку він буде перехоплений блоком catch, який йде раніше (ближче до блоку try).
Як же може виникнути ситуація, що один виняток можуть перехопити кілька блоків catch?
Усі винятки об'єднані в єдину ієрархію за допомогою успадкування — дивися схему.

Об'єкт-виняток типу ArithmeticException може бути присвоєно змінній типу ArithmeticException, а також змінним його класів-батьків: RuntimeException, Exception і Throwable — дивися схему.
Детальніше про успадкування та класи-батьки ми поговоримо на 21 рівні.
Ось цей код буде чудово компілюватися:
| Переваги успадкування: |
|---|
|
Тому і перехопити виняток типу ArithmeticException можна блоками catch будь-якого з 4-х наведених вище типів.
Приклад 1:
| Код | Вивід на екран |
|---|---|
|
|
У цьому прикладі виняток ArithmeticException може бути перехоплено як блоком catch(Exception e), так і блоком catch(ArithmeticException e). Він буде перехоплений тим блоком, який розташований ближче до блоку try — першим блоком catch.
Щоб не було несподіванок, найкраще блоки catch, які можуть захопити майже всі винятки, розміщувати ближче до кінця списку блоків catch.
Тип Throwable може перехоплювати усі можливі виключення в Java, якщо його розмістити в першому блоці catch - код не скомпілюється, оскільки компілятор розуміє, що в коді є недосяжні блоки коду.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ