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.

Объявляется класс 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);
        }
    }
}

В методе может возникнуть исключительная ситуация, которая вызовет исключение типа NegativeNumberException. Поэтому в объявлении метода присутствует ключевое слово throws с именем исключения

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

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

Отрицательное число: Exception: -2.0 is a negative number!!!
Summ = 0

 


Связанные темы