Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
GoslingJava2.doc
Скачиваний:
139
Добавлен:
23.02.2016
Размер:
2.39 Mб
Скачать

7.2. Оператор throw

Исключения возбуждаются оператором throw, которому в качестве параметра передается объект. Например, вот как выглядит реализация replaceValue в классе AttributedImpl из главы 4:

public void replaceValue(String name, Object newValue)

throws NoSuchAttributeException

{

Attr attr = find(name); // Искать attr

if (attr == null) // Если атрибут не найден

throw new NoSuchAttributeException(name, this);

attr.valueOf(newValue);

}

МетодreplaceValueсначалаищетимяатрибутавтекущемобъектеAttr.Если атрибут не найден, то возбуждается объект-исключение типа NoSuch AttribiteException и его конструктору предоставляются содержательные данные. Исключения являются объектами, поэтому перед использованием их необходимо создать. Если атрибут не существует, то его значение заменяется новым.

Разумеется, исключение может быть порождено вызовом метода, внутри которого оно возбуждается.

7.3. Условие throws

Первое, что бросается в глаза в приведенном выше методе replace Value,— это список проверяемых исключений, которые в нем возбуждаются. В Java необходимо перечислить проверяемые исключения, возбуждаемые методом, поскольку программист при вызове метода должен знать их в такой же степени, в какой он представляет себе нормальное поведение метода. Проверяемые исключения, возбуждаемые методом, не уступают по своей важности типу возвращаемого значения— и то и другое необходимо объявить.

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

Внутри метода разрешается возбуждать исключения, являющиеся расширениями типа Exception в условии throws, поскольку всегда допускается полиморфно использовать класс вместо его суперкласса. Метод может возбуждать несколько различных исключений, являющихся расширениями одного конкретного класса, и при этом объявить в условии throws всего один суперкласс. Тем не менее, поступая таким образом, вы скрываете от работающих с методом программистов полезную информацию, потому что они не будут знать, какие из возможных расширенных типов исключений возбуждаются методом. В целях надлежащего документирования условие throws должно быть как можно более полным и подробным.

Контракт, определяемый условием throws, обязан неукоснительно соблюдаться— можно возбуждать лишь те исключения, которые указаны в данном условии. Возбуждение любого другого исключения (прямое, с помощью throw, или косвенное, через вызов другого метода) является недопустимым. Отсутствие условия throws не означает, что метод может возбуждать любые исключения; наоборот, оно говорит о том, что он не возбуждает никаких исключений.

Все стандартные исключения времени выполнения (такие, как ClassCast Exception и ArithmeticException) представляют собой расширения класса RuntimeException. О более серьезных ошибках сигнализируют исключения, которые являются расширениями класса Error и могут возникнуть в произвольный момент в произвольной точке программы. RuntimeException и Error— единственные исключения, которые не нужно перечислять в условии throws; они являются общепринятыми и могут возбуждаться в любом методе, поэтому компилятор не проверяет их. Полный список классов стандартных непроверяемых исключений приведен в Приложении Б.

Инициализаторы и блоки статической инициализации не могут возбуждать проверяемые исключения, как прямо, так и посредством вызова метода, возбуждающего исключение. Во время конструирования объекта нет никакого способа перехватить и обработать исключение. При инициализации полей выход заключается в том, чтобы инициализировать их внутри конструктора, который может возбуждать исключения. Для статических инициализаторов можно поместить инициализацию в статический блок, который бы перехватывал и обрабатывал исключение. Статические блоки не возбуждают исключений, но могут перехватывать их.

Java довольно строго подходит к обработке проверяемых исключений, поскольку это помогает избежать программных сбоев, вызванных невниманием к ошибкам. Опыт показывает, что программисты забывают про обработку ошибок или откладывают ее на будущее, которое так никогда и не наступает. Условие throws ясно показывает, какие исключения возбуждаются методом, и обеспечивает их обработку.

При вызове метода, у которого в условии throws приведено проверяемое исключение, имеются три варианта:

  • Перехватить исключение и обработать его.

  • Перехватить исключение и перенаправить его в обработчик одного из ваших исключений, для чего возбудить исключение типа, объявленного в вашем условии throws.

  • Объявить данное исключение в условии throws и отказаться от его обработки в вашем методе (хотя в нем может присутствовать условие finally, которое сначала выполнит некоторые завершающие действия; подробности приводятся ниже).

При любом из этих вариантов вам необходимо перехватить исключение, возбужденное другим методом; это станет темой следующего раздела.

Упражнение 7.1

Создайте класс-исключение ObjectNotFoundException для класса Linked List, построенного нами в предыдущих упражнениях. Включите в него метод find, предназначенный для поиска объектов в списке, который либо возвращает нужный объект LinkedList, либо возбуждает исключение, если объект отсутствует в списке. Почему такой вариант оказывается более предпочтительным, нежели возврат значения null для ненайденного объекта? Какие данные должны входить в ObjectNotFoundException?

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]