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

7.5. Когда применяются исключения

В начале этой главы мы воспользовались выражением “неожиданное ошибочное состояние”, чтобы описать момент возбуждения исключения. Исключения не предназначаются для простых, предсказуемых ситуаций. Например, достижение конца входного потока является заранее предсказуемым, так что проверка на “исчерпание” потока является частью ожидаемого поведения метода. Код возврата, сигнализирующий о конце ввода, и проверка его при вызове также выглядят вполне разумно— к тому же такую конструкцию оказывается проще понять. Сравним типичный цикл, в котором используется флаг возврата

while ((token = stream.next()) != Stream.END)

process(token);

stream.close();

с другим циклом, в котором о достижении конца ввода сигнализирует исключение:

try {

for (;;) {

process(stream.next());

}

} catch (StreamEndException e) {

stream.close();

}

В первом случае логика выполнения программы оказывается прямолинейной и понятной. Цикл выполняется до тех пор, пока не будет достигнут конец входного потока, после чего поток закрывается. Во втором случае цикл выглядит так, словно он выполняется бесконечно. Если не знать о том, что о конце ввода сигнализирует StreamEndException, то становится непонятно, когда же происходит выход из цикла. Впрочем, даже если вы догадываетесь о существовании StreamEndException, то факт завершения цикла оказывается вынесенным из его тела (for) во внешний блок try, что затрудняет понимание происходящего.

Встречаются ситуации, в которых невозможно найти приемлемый код возврата. Например, в классе, представляющем поток значений типа double, может содержаться любое допустимое double, поэтому числовой маркер конца потока невозможен. Более разумный подход предусматривает специальный метод eof для проверки конца потока, который должен выполняться перед каждой операцией чтения:

while (!stream.eof())

process(stream.nextDouble());

stream.close();

С другой стороны, попытка чтения после достижения конца файла оказывается непредсказуемой. Она свидетельствует о том, что программа не заметила конца входного потока и теперь пытается сделать что-то такое, чего делать ни в коем случае не следует. Перед нами— отличная возможность применить исключение ReadPastEndException. Подобные действия выходят за границы ожидаемого поведение класса-потока, так что возбуждение исключения в данном случае оказывается вполне уместным.

Решить, какая ситуация является предсказуемой, а какая— нет, порой бывает нелегко. Главное— не злоупотреблять исключениями для сообщений о предсказуемых ситуациях.

Упражнение 7.2

Как, по вашему мнению, программа должна сообщать программисту о следующих ситуациях:

  • Программа пытается присвоить отрицательное значение вместимости машины в объекте PassengerVehicle.

  • В файле конфигурации, используемом для задания начального состояния объекта, обнаружена синтаксическая ошибка.

  • Метод, который ищет в строковом массиве указанное программистом слово, не может найти ни одного экземпляра такого слова.

  • Файл, передаваемый методу open, не существует.

  • Файл, передаваемый методу open, существует, но система безопасности не разрешает пользователю работать с ним.

  • При попытке установить сетевое соединение с удаленным процессом-сервером не удается связаться с удаленным компьютером.

  • Во время взаимодействия с удаленным процессом-сервером прерывается сетевое соединение.

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