Как использовать исключительные ситуации

Обычно исключительные ситуации применяют слишком часто.

 

1. Обработка исключительных ситуаций не может заменить собой простую проверку.

Для иллюстрации мы написали фрагмент программы, использующей встроенный класс Stack. Программа, приведенная ниже, делает 1000000 попыток вытолкнуть элемент из пустого стека. Сначала она определяет, пуст ли стек.

 

if (!s.empty()) s.pop();

 

Затем мы заставляем ее выталкивать элемент из стека, не обращая внимания на то, что он пуст. После этого мы перехватываем исключительную ситуацию EmptyStackException, которая сообщает нам, что мы не правы.

 

 

  try

 { 

s.pop();

 }

  catch (EmptyStackException e)

 {

 }

 

Текст программы:

 

/* @version 1.10 2000-06-03 @author Cay Horstmann */

import java.util.*;

public class ExceptionalTest

public static void main(String[] args)

int i = 0;

int ntry = 1000000;

Stack s = new Stack();

long s1;

long s2;

    // ntry раз проверить пуст ли стек

System. out. println("Testing for empty stack");

s1 = new Date().getTime();

for (i = 0; i <= ntry; i++)

    if (!s.empty()) s.pop();

s2 = new Date().getTime();

System. out. println((s2 - s1) + " milliseconds");

        

// ntry раз извлекается элемент из пустого стека

// и генерируется исключение

System. out. println("Catching EmptyStackException");

s1 = new Date().getTime();

for (i = 0; i <= ntry; i++)

{

    try

    { 

       s.pop();

    }

    catch (EmptyStackException e)

    {

    }

}        

s2 = new Date().getTime();

System. out. println((s2 - s1) + " milliseconds");

}

}

 

Время, которое мы затратили на эти операции, равно соответственно 94 мс и 2422 мс.

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

 

2. Не мелочитесь!

Многие программисты каждый оператор помещают в отдельный блок try.

OutputStream out;

Stack s;

 

for (i = 0; i < 100; i++)

{

try

{

n = s.pop();

}

catch (EmptyStackException s)

{

// Стек пуст,

}

try

{

out.writeInt(n);

}

catch (IOException e)

{

// Проблемы при записи данных в файл.

}

}

 

При таком подходе размер вашей программы стремительно увеличивается. Подумайте о задаче, которую должна решать ваша программа. В данном случае мы хотим вытолкнуть из стека 100 чисел и записать их в файл. (Неважно как — это всего лишь пример.) Само по себе возбуждение исключительной ситуации не решает проблем. Если стек пуст, он не заполнится по мановению волшебной палочки. Если при записи в файл возникает ошибка, она не исчезнет сама собой. Следовательно, имеет смысл поместить в блок try весь фрагмент программы. Если хотя бы одна из операций даст сбой, можно отказаться от решения всей задачи.

try

{

for (i = 0; i < 100; i++)

{

n = s.pop ();

out.writeInt(n);

}

}

catch(IOException e)

{

// Проблемы при записи данных в файл,

}

catch(EmptySTackException e)

{

// Стек пуст.

}

 

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

 

3. Не заглушайте исключительные ситуации!

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

 

public Image loadImage(String s)

{

try

{

Код, способный сгенерировать исключение.

}

catch (Exception e)

{} // Действия не выполняются!

}

 

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

 

4. Не стыдитесь передавать исключительные ситуации другим обработчикам!

Некоторые программисты считают себя обязанными перехватывать все исключительные ситуации, которые они возбуждают. Вызывая метод, возбуждающий некоторую исключительную ситуацию, например, конструктор класса FileInputStream или метод readLine, они инстинктивно перехватывают исключительные ситуации, которые могут быть сгенерированы ими. Зачастую оказывается предпочтительнее передатьисключительную ситуацию другому обработчику, а не обрабатывать ее самому. Методы более высокого уровня лучше информируют пользователя об ошибке.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: