Кілька інструкцій catch після інструкції try
У деяких випадках один і той же блок програмного коду може порушувати виключення різних типів. Для того щоб обробляти подібні ситуації, Java дозволяє використовувати будь-яку кількість catch-розділів для try-блоку. Найбільш спеціалізовані класи виключень повинні йти першими, оскільки жоден підклас не буде досягнутий, якщо поставити його після суперкласу.
Щоб у програмі TryCatch.java перехоплювався також виняток типу ArithmeticException, достатньо після першої інструкції catch додати ще одну, в якій у параметрах буде вказуватися виняток типу ArithmeticException:
Щоб у програмі TryCatch.java перехоплювався також виняток типу ArithmeticException, достатньо після першої інструкції catch додати ще одну, в якій у параметрах буде вказуватися виняток типу ArithmeticException:
package inwe;
class TryCatch {
...
try {
// masuv[14] = 28;
zminna = 1 / 0;
System.out.println(В блоці try немає помилок!);
}
catch(IndexOutOfBoundsException vunjatok) { /* інструкція catch перехоплює об’єкт класу IndexOutOfBoundsException */
/* Якщо даний об'єкт перехоплюється інструкцією сatch, то виводиться повідомлення про помилку та вміст об'єкту винятку */
System.out.println(Помилка виконання програми: + vunjatok);
}
catch(ArithmeticException vunjatok) { /* інструкція catch перехоплює об’єкт класу ArithmeticException */
/* Якщо даний об'єкт перехоплюється інструкцією сatch, то виводиться повідомлення про помилку та вміст об'єкту винятку */
System.out.println(Помилка виконання програми: + vunjatok);
}
...
}
В блоці try програмний код виконується до виникнення помилки, після чого виконання програми переходить до інструкцій catch: спочатку до першої, потім до другої і т. д., доки не здійсниться перехоплення. Якщо в блоці інструкції try не закоментовувати жодну стрічку, то виникне помилка виходу за межі масиву, яку перехопить перша інструкція catch:
...
try {
masuv[14] = 28; // створиться виняток типу IndexOutOfBoundsException
// Наступний код виконуватися не буде
zminna = 1 / 0;
System.out.println(В блоці try немає помилок!);
}
// Виконається перехоплення цією інструкцією catch
catch(IndexOutOfBoundsException vunjatok) {
System.out.println(Помилка виконання програми: + vunjatok);
}
Якщо в блоці інструкції try закоментувати перший вираз, то:
...
try {
// masuv[14] = 28;
zminna = 1 / 0; // створиться виняток типу ArithmeticException
// Наступний код виконуватися не буде
System.out.println(В блоці try немає помилок!);
}
...
// Виконається перехоплення цією інструкцією catch
catch(ArithmeticException vunjatok) {
System.out.println(Помилка виконання програми: + vunjatok);
}
Якщо в блоці інструкції try закоментувати обидва вирази із помилками, то:
...
try {
// masuv[14] = 28;
// zminna = 1 / 0;
// Виведеться повідомлення у консоль
System.out.println(В блоці try немає помилок!);
}
Важливою є послідовність написаних після try інструкцій catch. Інструкції catch перехоплюють винятки у тому порядку, в якому вони записані — спочатку перевіряється перша інструкція, якщо вона не перехоплює такий тип винятку, то перевіряється наступна і так далі...
Надкласи перехоплюють усі винятки їхніх підкласів. Наприклад, якщо в інструкції перехоплюється виняток класу Exception:
catch(Exception vunjatok) {
...
}
то цією інструкцією також будуть перехоплюватися винятки його підкласу RuntimeException і також винятки класу AriphmeticException, який є підкласом класу RuntimeException. Тому буде помилкою після інструкції catch, яка перехоплює винятки надкласу, писати інструкцію catch, яка буде перехоплювати винятки підкласу, адже всі винятки перехоплюватимуться першою інструкцією:
try {
...
}
catch(Exception vunjatok) { /* перехоплюються усі винятки класу Exception, а також всі
винятки його підкласів, таких як RuntimeException */
...
}
catch(RuntimeException vunjatok) { /* помилка, ця інструкція ніколи не виконуватиметься,
так як усі винятки були перехоплені надкласом Exception попередньої інструкції */
...
}
Також для перехоплення кількох типів винятків можна користуватися оператором АБО(|).
try {
...
}
catch(NullPointerException | ArithmeticException vunjatok) { /* перехоплюються винятки
класу NullPointerException або винятки класу ArithmeticException */
...
}
Наступна програма перехоплює два різних типи винятків, причому за цими двома спеціалізованими обробниками йде розділ catch загального призначення, що перехоплює всі підкласи класу Throwable.
class MultiCatch {
public static void main(String args[]) {
try {
int a = args.length;
System.out.println("a = " + a);
int b = 42 / a;
int c[] = { 1 };
c[42] = 99;
}
catch (ArithmeticException e) {
System.out.println("ділення на нуль: " + e);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("неправильний індекс масиву: " + e);
}}
public static void main(String args[]) {
try {
int a = args.length;
System.out.println("a = " + a);
int b = 42 / a;
int c[] = { 1 };
c[42] = 99;
}
catch (ArithmeticException e) {
System.out.println("ділення на нуль: " + e);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("неправильний індекс масиву: " + e);
}}