1. Оператор throw

Виняток, поки його не викинуто в систему або коли його вже перехоплено блоком catch — це, власне, просто об'єкт класу, успадкованого від Exception (точніше, від Throwable). Ніяких магічних особливостей сам об'єкт-виняток не має.

Уся логіка роботи винятків — це просто особливий сценарій поведінки Java-машини, коли в її середовище виконання вкинуто виняток.

Ви завжди можете знову вкинути Java-машині виняток, який щойно перехопили. Для цього слід використовувати оператор throw:

throw виняток;

Приклад:

Код Виведення на екран
try
{
   int d = 2/0;
}
catch(Exception except)
{
   System.out.println("Перехопили виняток");
   throw except;
}
Перехопили виняток

У цьому коді ми перехопили виняток, вивели на екран відповідний напис і знову викинули цей виняток.

Повторно кинутий виняток не може бути захоплено іншими блоками catch цього самого try-блока.


2. Свій виняток

До речі, ви можете самі створити об'єкт-виняток: це просто об'єкт типу Exception або успадкованого від нього класу. І викинути його.

Це простіше, ніж здається. Приклад:

Код Виведення на екран
try
{
   throw new RuntimeException();
}
catch(Exception except)
{
   System.out.println("Перехопили виняток");
   throw except;
}
Перехопили виняток

У прикладі вище ми створили новий об'єкт-виняток типу RuntimeException і миттєво кинули його за допомогою оператора throw.

Його відразу захопить блок catch, оскільки тип RuntimeException успадковано від типу Exception. Код catch(Exception except) захоплює об'єкти-винятки всіх класів, успадкованих від класу Exception.



3. Ключове слово finally

Ще один важливий момент. Іноді програмісту потрібно виконати певні дії незалежно від того, був у коді виняток чи ні. Наприклад, у коді ми відкрили файл для запису, а відкритий файл треба обов'язково закрити викликом методу close().

try
{
   код, де може виникнути помилка
}
catch(ТипВинятку ім'я)
{
   код обробки винятку
}
finally
{
   код, який потрібно виконати в будь-якому разі
}

Для виконання таких обов'язкових дій до оператора try-catch додали ще один блок — finally й отримали оператор try-catch-finally. Отакий приблизно вигляд це має:

Приклад:

FileInputStream source = null;
try
{
   source = new FileInputStream("c:\\note.txt");
   source.read();
}
catch(Exception except)
{
   System.out.println("Перехопили виняток");
   throw except;
}
finally
{
   if (source != null)
      source.close();
}

Код у блоці finally буде виконано в будь-якому випадку незалежно від того, був виняток чи ні. Навіть якщо виняток виник і його не було перехоплено, блок finally все одно буде виконано.

До речі, якщо ви не хочете перехоплювати виняток, а блок finally вам потрібен, використовуйте скорочений запис блока try-catch-finallytry-finally. Він має приблизно такий вигляд:

try
{
   код, де може виникнути помилка
}
finally
{
   код, який потрібно виконати в будь-якому разі
}