Мои Конспекты
Главная | Обратная связь


Автомобили
Астрономия
Биология
География
Дом и сад
Другие языки
Другое
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Металлургия
Механика
Образование
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Туризм
Физика
Философия
Финансы
Химия
Черчение
Экология
Экономика
Электроника

Избегайте ненужных обрабатываемых исключений



Обрабатываемые исключения -' замечательная особенность языка программиро­вания Java. В отличие от возвращаемых кодов, они заставляют программиста отсле­живать условия возникновения исключений, что значительно повышает надежность приложения. Это означает, что злоупотребление обрабатываемыми исключениями может сделать API менее удобным для использования. Если метод инициирует одно или несколько обрабатываемых исключений, то в программном коде, из которого этот метод был вызван, должна присутствовать обработка этих исключений в виде одного или нескольких блоков catch, либо должно быть декларировано, что этот код сам инициирует исключения и передает их дальше. В любом случае перед программистом стоит нелегкая задача.

Такое решение оправданно, если даже при надлежащем применении интерфейса API невозможно предотвратить возникновение условий для исключительной ситуа­ции, однако программист, пользующийся данным API, столкнувшись с этим исключе­нием, мог бы предпринять какие-либо полезные действия. Если не выполняются оба этих условия, лучше пользоваться необрабатываемым исключением. Роль лакмусовой бумажки в данном случае играет вопрос: как программист будет обрабатывать исклю­чение? Является ли это решение лучшим:

} catch(TheCheckedException е) {

throw new Error("Assertion error");

// Условие не выполнено. Этого не должно быть никогда!

}

 

А что скажете об этом:

} catch(TheCheckedException e) {

e.printStackTrace(); //Ладно, закончили работу.

System. exit( 1); }

 

Если программист, применяющий API, не может сделать ничего лучшего, то боль­ше подходит необрабатываемое исключение. Примером исключения, не выдерживаю­щего подобной проверки, является CloneNotSupportedException. Оно инициируется

 

 

 

методом Object. сlоnе, который должен использоваться лишь для объектов, реализу­ющих интерфейс Cloneable (статья 10). Блок catch практически всегда соответствует невыполнению утверждения. Так что обрабатываемое исключение не дает програм­мисту преимуществ, но требует от последнего дополнительных усилий и усложняет программу.

Дополнительные действия со стороны программиста, связанные с обработкой обрабатываемого исключения, значительно увеличиваются, если это единственное исключение, инициируемое данным методом. Если есть другие исключения, метод будет стоять в блоке try, так что для этого исключения понадобится всего лишь еще один блок catch. Если же метод инициирует только одно обрабатываемое исключение, оно будет требовать, чтобы вызов соответствующего метода был помещен в блок try. В таких условиях имеет смысл подумать: не существует ли какого-либо способа избежать обрабатываемого исключения.

Один из приемов, позволяющих превратить обрабатываемое исключение в необ­рабатываемое, состоит в раз биении метода, инициирующего исключение, на два мето­да, первый из которых будет возвращать булево значение, указывающее, будет ли инициироваться исключение. Таким образом, в результате преобразования АРI после­довательность вызова

 

// Вызов с обрабатываемым исключением

try {

obj.action(args);

catch(TheCheckedException е) {

// Обработать исключительную ситуацию

}

 

принимает следующий вид:

 

// Вызов с использованием метода проверки состояния

// и необрабатываемого исключения

if (obj.actionPermitted(args)) {

obj.action(args); }

else{ }

// Обработать исключительную ситуацию

 

Такое преобразование можно использовать не всегда, Если же оно допустимо, это может сделать работу с АРI более удобной. Хотя второй вариант последовательности вызова выглядит не лучше первого, полученный АРI имеет большую гибкость, В ситуации, когда программист знает, что вызов будет успешным, или согласен на завершение потока в случае неудачного вызова, преобразованный АРI позволяет использовать следующую упрощенную последовательность вызова:

 

obj,aotion(args):

 

 

Если вы предполагаете, что применение упрощенной последовательности вызова будет нормой, то описанное преобразование АР! приемлемо. API, полученный в ре­зультате этого преобразования, в сущности, тот же самый, что и АР! с методом "проверки состояния" (статья 39). Следовательно, к нему относятся те же самые предупреждения: если к объекту одновременно и без внешней синхронизации могут иметь доступ сразу несколько потоков или этот объект может менять свое состояние по команде извне, указанное преобразование использовать не рекомендуется. Это связано с тем, что в промежутке между вызовом actionPermitted и вызовом action состояние объекта может успеть поменяться. Если метод actionPermitted при необхо­димости и мог бы дублировать работу метода action, то от преобразования, вероятно, стоит отказаться по соображениям производительности.

 




Поиск по сайту:







©2015-2020 mykonspekts.ru Все права принадлежат авторам размещенных материалов.