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

...

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

Используйте исключения лишь в исключительных ситуациях





Помощь в ✍️ написании работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

 

Однажды, если вам не повезет, вы сделаете ошибку в программе, например, такую:

// Неправильное использование исключений. Никогда так не делайте!

try {

int i = 0;

while(true)

а[i++]. f();

} catch(ArraylndexOutOfBoundsException е) { }

 

Что делает этот код? Изучение кода не вносит полной ясности, и это достаточная причина, чтобы им не пользоваться. Здесь приведена плохо продуманная идиома для циклического перебора элементов в массиве. Когда производится попытка обращения к первому элементу за пределами массива, бесконечный цикл завершается иниции­рованием исключительной ситуации ArraylndexOutOfBoundException, ее перехватом и последующим игнорированием. Предполагается, что это эквивалентно стандартной идиоме цикла по массиву, которую узнает любой программист java:

for (int i = 0; i < a.length; i++)

a[i].f();

 

 

Но почему же кто-то выбрал идиому, использующую исключения, вместо другой, испытанной и правильной? Это вводящая в заблуждение попытка улучшить произво­дительность, которая исходит из ложного умозаключения, что, поскольку виртуальная машина проверяет границы при всех обращениях к массиву, обычная проверка на завершение цикла (i < a.length) избыточна и ее следует устранить. В этом рассуж­дении неверны три момента:

 

· Так как исключения создавались для применения в исключительных условиях, лишь очень немногие реализации JVM пытаются их оптимизировать (если таковые есть вообще). Обычно создание, инициирование и перехват исключения дорого обходится системе

 

· Размещение кода внутри блока try-catch препятствует выполнению определенных процедур оптимизации, которые в противном случае могли бы быть исполнены в современных реализациях jVM.

 

· Стандартная идиома цикла по массиву вовсе не обязательно приводит к выполнению избыточных проверок, в процессе оптимизации некоторые современные реализации jVM отбрасывают их.

Практически во всех современных реализациях jVM идиома, использующая ис­ключения, работает гораздо медленнее стандартной идиомы. На моей машине идиома, использующая исключения, выполняет цикл от 0 до 99 в семьдесят раз медленней стандартной.

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

Мораль проста: исключения, как и подразумевает их название, должны при­меняться лишь для исключительных ситуаций, при обычной обработке исполь­зовать их не следует никогда. Вообще говоря, вы всегда должны предпочитать стандартные, легко распознаваемые идиомы идиомам с ухищрениями, предлагающим лучшую производительность. Даже если имеет место реальный выигрыш в производи­тельности, он может быть поглощен неуклонным совершенствованием реализаций jVM. А вот коварные ошибки и сложность поддержки, вызываемые чересчур хитро­умными идиомами, наверняка останутся.

 

 

 

Этот принцип относится также к проектированию АРI. Хорошо спроектиро­ванный API не должен заставлять своих клиентов использовать исключения для обычного управления потоком вычислений. Если в классе есть метод, зависящий от состояния (state-dependent), который может быть вызван лишь при выполнении определенных непредсказуемых условий, то в этом же классе, как правило, должен присутствовать отдельный метод, проверяющий состояние (state-testing), который по­казывает, можно ли вызывать первый метод. Например, класс Iterator имеет завися­щий от состояния метод next, который возвращает элемент для следующего прохода цикла, а также соответствующий метод проверки состояния hasNext. Это позволяет применять для просмотра коллекции в цикле следующую стандартную идиому:

for (Iterator i = collection. iterator(); i. hasNext(); ) {

Foo foo = (Foo) i.next(); }

 

Если бы в классе Iterator не было бы метода hasNext, клиент был бы вынужден использовать следующую конструкцию:

// Не пользуйтесь этой отвратительной идиомой

// для просмотра коллекции в цикле!

 

try {

Iterator i = collection.iterator();

while(true) {

Foo foo = (Foo) i.next();

}

} catch (NoSuchElementException е) { }

 

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

В качестве альтернативы отдельному методу про верки состояния можно исполь­зовать особый зависящий от состояния метод: он будет возвращать особое значение, например null, при вызове для объекта, имеющего неподходящее состояние. Для класса Iterator этот прием не годится, поскольку null является допустимым значени­ем для метода next.

Приведем некоторые рекомендации, которые помогут вам сделать выбор между методом проверки состояния и особым возвращаемым значением. Если к объекту возможен одновременный доступ без внешней синхронизации или если смена его СОСТОJШИЙ инициируется извне, может потребоваться прием с особым возвращаемым

 

 

 

 

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

 

Доверь свою работу ✍️ кандидату наук!
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой



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







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