Java. Виключення. Оператори throw, throws. Приклади

Java. Виключення. Оператори throw, throws. Приклади

Вивчення даної теми базується на використанні наступних тем:


Зміст



1. Яке призначення ключового слова throw? Загальна форма

Виключення може генерувати:

  • виконавче середовище Java;
  • прикладна програма. У цьому випадку програма повинна використати оператор throw.

Загальна форма оператора throw має такий вигляд

throw instance;

тут instance – об’єкт класу Throwable або похідного від нього підкласу. Більш детально про клас Throwable можна переглянути тут.

Якщо оператор throw використовується у блоці try…catch, то в загальному вигляд блоку наступний

...
try {
    // ...

    throw new ThrowableClass(parameters); // якщо виключна ситуація, то згенерувати виключення

    // ...
}
catch (ThrowableClass e) {
    // обробити виключення
    // ...
}
...

тут

  • ThrowableClass – клас, породжений від класу Throwable або RunTimeException;
  • e – екземпляр класу, що відповідає виключенню яке перехоплюється;
  • parameters – параметри конструктора класу ThrowableClass. Як правило, конструктори класів породжених від Throwable або RunTimeException мають два варіанти реалізації: без параметрів або з одним рядковим параметром, що описує виключну ситуацію.

У рядку

throw new ThrowableClass(parameters);

створюється виключення з допомогою оператора new, який виділяє пам’ять та викликає конструктор. Для усіх стандартних виключень існує два конструктори:

  • конструктор за замовчуванням. Цей конструктор не містить параметрів;
  • конструктор з одним параметром, який представляє собою рядок. У рядку вказується інформація про виключення. Наприклад, рядок “ділення на нуль”.

 

2. Приклад генерування виключення з допомогою оператора throw у блоці try. Створення класу, що розв’язує квадратне рівняння

Генерування виключення здійснюється з допомогою ключового слова throw, яке може зустрічатись у блоці try (генерування виключення вручну). Наприклад, наведений нижче код демонструє зразок генерування виключення вручну з допомогою засобу throw

У прикладі показано як генерується виключення з допомогою оператора throw. Оголошується клас QuadraticEquation який розв’язує квадратне рівняння.

У класі оголошуються такі елементи:

  • внутрішні змінні a, b, c що є коефіцієнтами рівняння;
  • внутрішні змінні x1, x2 що є розв’язками рівняння (у випадку, якщо рівняння має розв’язок);
  • конструктор класу;
  • метод Solution(). У цьому методі використовується обробка можливих виключних ситуацій: ділення на 0 та корінь з від’ємного числа.

Текст класу наступний:

// генерування виключення оператором throw
// розв'язок квадратного рівняння
class QuadraticEquation {
    double a,b,c,x1,x2;

    // конструктор
    QuadraticEquation(double a, double b, double c)  {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    // метод, що роз'язує квадратне рівняння
    void Solution() {
        double d; // дискримінант

        try {
            d = b*b - 4*a*c;

            // врахувати ділення на 0
            if (a==0)
                throw new ArithmeticException("Ділення на 0."); // створити виключення

            // врахувати корінь з від'ємного числа
            if (d<0)
                throw new ArithmeticException("Рівняння не має коренів."); // створити виключення

            x1 = (-b - Math.sqrt(d))/(2*a);
            x2 = (-b + Math.sqrt(d))/(2*a);

            System.out.println("x1 = " + x1);
            System.out.println("x2 = " + x2);
        }
        catch (ArithmeticException e) {
            System.out.println(e); // вивести виключення, створене у блоці try
        }
    }
}

У методі Solution() перехоплюються дві виключні ситуації:

  • ділення на 0;
  • корінь з від’ємного числа.

Для цього з допомогою оператора throw створюється відповідний екземпляр класу ArithmeticException. Клас ArithmeticException є підкласом класу RuntimeException. Клас ArithmeticException використовується коли виникла арифметична помилка. У нашому випадку маємо арифметичні помилки двох видів: ділення на 0 та корінь з від’ємного числа. Тому, у блоці try створюється відповідний екземпляр виключення з рядком опису помилки

...
// врахувати ділення на 0
if (a==0)
    throw new ArithmeticException("Ділення на 0."); // створити виключення

// врахувати корінь з від'ємного числа
if (d<0)
    throw new ArithmeticException("Рівняння не має коренів."); // створити виключення
...

Обробка кожної з помилок в операторі catch є стандартною. Тому, просто виводиться текст опису виключення

...
catch (ArithmeticException e) {
    System.out.println(e); // вивести виключення, створене у блоці try
...

Нижче наводиться демонстрація використання класу в коді

public class Train02 {

    public static void main(String[] args) {
        // створити екземпляр класу
        QuadraticEquation qE = new QuadraticEquation(1,1,1);
        qE.Solution(); // викликати метод, що розв'язує рівняння
        System.out.println("-------------------------");

        // створити інший екземпляр класу
        QuadraticEquation qE2 = new QuadraticEquation(0,3,5);
        qE2.Solution();
        System.out.println("-------------------------");

        QuadraticEquation qE3 = new  QuadraticEquation(2,3,-5);
        qE3.Solution();
    }
}

Результат виконання програми наступний:

java.lang.ArithmeticException: Рівняння не має коренів.
-------------------------
java.lang.ArithmeticException: Ділення на 0.
-------------------------
x1 = -2.5
x2 = 1.0

 

3. Які типи заборонено використовувати для генерування виключень оператором throw?

Для генерування виключень оператором throw заборонено використовувати:

  • примітивні типи (наприклад int, char);
  • класи за винятком класів, успадкованих з класу Throwable. Наприклад, заборонено використовувати клас String чи інші класи.

 

4. Яким чином створити власний клас виключення? Приклад

Щоб створити власний клас виключення потрібно, щоб цей клас був успадкований від класу Exception. Після того, як клас успадкований від класу Exception він вже є частиною системи виключень Java і його можна використовувати як інші класи виключень (наприклад ArithmeticException, ArrayIndexOfBoundsException та інші).

Більш детально про використання класу Exception та інших класів описується в темі:

  • Класи Java для обробки виключних ситуацій. Приклади використання.

Якщо клас успадкований від класу Exception то не обов’язково навіть реалізовувати якісь додаткові операції в цьому класі. В будь-якому випадку, виключення, що відповідає цьому класу, буде коректно перехоплюватись у блоці catch.

Клас Exception не містить методів. Однак, цей клас є успадкований від класу Throwable. У класі Throwable є доступні ряд методів, які можна перевизначити у власному класі виключення.

Приклад. З метою демонстрації оголошується клас NegativeNumberException. У нашому випадку цей клас представляє собою виключення, яке генерується у випадку, якщо число є від’ємне. У класі оголошуються:

  • внутрішня змінна value. Ця змінна введена є необов’язковою і вводиться у демонстраційних цілях;
  • конструктор, який є необов’язковий;
  • метод toString(), який перевизначає однойменний метод класу Throwable. Цей метод виводить відповідне повідомлення.
// Оголосити клас, який є похідний від класу Exception
// Даний клас є частиною системи виключень Java
class NegativeNumberException extends Exception {
    private double value;

    // деякий конструктор класу
    NegativeNumberException(double _value) {
        value = _value;
    }

    // перевизначений метод toString() класу Throwable,
    // цей метод виводить інформацію про виключення типу NegativeNumberException
    public String toString() {
        String msg = "Exception: " + value + " is a negative number!!!";
        return msg;
    }
}

public class Train04 {

    public static void main(String[] args) {
        // демонструється генерування виключення типу NegativeNumberException
        double value;

        try {
            value = -5; // від'ємне число

            // якщо від'ємне значення, то згенерувати виключення типу NegativeNumberException
            if (value<0)
                throw new NegativeNumberException(value);
        }
        catch (NegativeNumberException e) {
            // вивести інформацію про виключення
            // викликається метод toString() класу NegativeNumberException
            System.out.println(e);
        }
    }
}

У вищенаведеному прикладі після оголошення

class NegativeNumberException extends Exception {
    // ...
}

клас NegativeNumberException стає складовою частиною ієрархії класів виключень Java. Тому можна його використовувати у блоці catch конструкції try…catch.

У функції main() навмисно генерується виключення типу NegativeNumberException у рядку

...
if (value<0)
    throw new NegativeNumberException(value);
...

У результаті програма переходить у блок catch, в якому виводиться інформація про виключення

...
catch (NegativeNumberException e) {
    System.out.println(e);
}
...

Фактично, викликається метод toString() класу NegativeNumberException. Якби метод toString() не був перевизначений у класі NegativeNumberException, тоді був би викликаний метод toString() класу Throwable.

Результат виконання програми

Exception: -5.0 is a negative number!!!

 

5. Яке призначення ключового слова throws? Загальна форма

Оператор throws використовується в оголошенні методу для того, щоб повідомити викликаючий код про те, що даний метод може згенерувати виключення яке він не обробляє. Це стосується усіх виключень крім:

  • класів Error та RuntimeException;
  • будь-яких підкласів, що успадковані з класів Error та RuntimeException.

Загальна форма використання оператора throws в методі має вигляд

type MethodName(parameters) throws exceptions_list {
    // ...
}

тут

  • type – тип, що повертає метод MethodName();
  • MethodName – ім’я методу;
  • parameters – параметри методу;
  • exception_list – перелік типів (класів) виключень розділених комою. Це є перелік виключень, які можуть бути згенеровані в методі MethodName.

 

6. Приклад використання оператора throws для методу, що генерує виключення

У прикладі оголошується клас NegativeNumberException похідний від класу Exception. Цей клас є класом виключення.

Також оголошується клас DemoThrows, який містить метод SumItems(), здатний викликати виключення типу NegativeNumberException.

Програмний код класів наступний

// Оголосити клас, який є похідний від класу Exception
// Даний клас є частиною системи виключень Java
class NegativeNumberException extends Exception {
    private double value;

    // деякий конструктор класу
    NegativeNumberException(double _value) {
        value = _value;
    }

    // перевизначений метод toString() класу Throwable,
    // цей метод виводить інформацію про виключення типу NegativeNumberException
    public String toString() {
        String msg = "Exception: " + value + " is a negative number!!!";
        return msg;
    }
}

// демонстрація виключення
class DemoThrows {
    int SumItems(int A[]) throws NegativeNumberException {
        int i, sum=0;
        for (i=0; i<10; i++) {
            // якщо індекс за межами масиву, то згенерувати виключення
            if (i>A.length)
                throw new ArrayIndexOutOfBoundsException("Індекс за межами масиву.");

            if (A[i]<0)
                throw new NegativeNumberException((double)A[i]);
            sum += A[i];
        }
        return sum;
    }
}

public class Train04 {
    public static void main(String[] args) {
        // виклик методу SumItems з класу DemoThrows
        int M[] = { 1, -2, 3, 4, 5, 6, 7 };
        DemoThrows dt = new DemoThrows(); // створити екземпляр класу DemoThrows
        int summ=0;

        try {
            // викликати метод, в якому генерується
            // виключення NegativeNumberException
            summ = dt.SumItems(M);
        }
        catch (NegativeNumberException e) {
            System.out.println("Від\'ємне число: "+e);
        }
        catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Перехоплено виключення: " + e);
        }
        finally {
            System.out.println("Summ = " + summ);
        }
    }
}

В методі SumItems() може виникнути виключна ситуація, яка викличе виключення типу NegativeNumberException. Тому, в оголошенні методу присутнє ключове слово throws з іменем виключення

...
int SumItems(int A[]) throws NegativeNumberException {
    ...
}
...

Результат роботи програми

Від'ємне число: Exception: -2.0 is a negative number!!!
Summ = 0

 


Зв’язані теми