Вопрос обработки исключений

У меня есть вопрос относительно обработки исключений. Рассмотрим следующий фрагмент кода Java.

        try{
            //code
        }catch(SubSubException subsubex){
            //code
        }catch(SubException subex){
            //code
        }catch(Exception ex){
            //code
        }

Я знаю, что это рекомендуемый способ обработки исключений. Но я могу добиться того же, используя следующий фрагмент кода.

        try{
            //code
        }catch ( Exception ex){
            if( ex instanceof SubException){              
                //code
            }else if(ex instanceof SubSubException){
                //code
            }else{
                //code
            }
        }

Может кто-нибудь сказать мне недостатки второго подхода?

8 ответов

Решение

Второй подход менее читабелен. Кроме того, обработка исключений в Pokemon никогда не является подходящим способом, хотя ваш "умный" трюк заключается в использовании ключевого слова instanceof. В любом случае, я не шучу и не шучу, но лучше всего писать код для людей, которые они будут читать и поддерживать, а не для компьютера.

Да, MadMurf указывает на самое важное отличие: проверка достижимости во время компиляции. Стандартная идиома ловит что-то вроде этого и по праву препятствует компиляции:

    try {
    } catch (IndexOutOfBoundsException iooe) {
    } catch (ArrayIndexOutOfBoundsException aiooe) {
    }

Аналог if/instanceof, предложенный в исходном вопросе, скомпилируется (а это НЕ то, что вы хотели бы, потому что он ошибочен).

Причина, по которой стандартная идиома отлавливает ошибку во время компиляции, приведена в JLS 14.21 Недоступные заявления.

  • Блок перехвата C доступен, если выполняются оба следующих условия:
    • [...]
    • В операторе try нет более раннего блока catch A, так что тип параметра C совпадает с типом параметра A или является его подклассом.

Чтобы дополнительно проиллюстрировать это, следующие компиляции:

    try {
    } catch (Exception e) {
        if (e instanceof Exception) {
        } else if (e instanceof Exception) {
        }
    }

Как вы можете видеть, эту идиому "ловить покемонов" гораздо сложнее поддерживать, поскольку она обходит некоторые из проверок достижимости во время компиляции, применяемые в стандартной идиоме.

Чтобы еще яснее понять, сделали ли вы это нарочно или нет, вы фактически изменили порядок, в котором вы проверяли исключения в исходном вопросе, и этот факт мог быть легко пропущен другими. Если SubSubException является подклассом SubException, второе условие if НИКОГДА не будет оцениваться, а его тело является фактически недоступным кодом.

Подход if/instanceof ОЧЕНЬ подвержен ошибкам.

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

Второй подход значительно менее читабелен, потому что:

  • это требует больше символов,

  • это требует более глубокого отступа,

  • это не идиоматично.

И ИМО, последнее самое главное. Вы должны писать свой код так, как этого ожидают другие Java-программисты.

Второй случай - это совершенно правильный java-код, но он имеет большую сложность Cyclomatic без добавления каких-либо дополнительных значений.

В качестве альтернативы при повторном заказе "ловли" исключений во втором примере. Если SubSubException расширяет SubException, вторая проверка никогда не будет достигнута....

просто нужно с осторожностью относиться к заказу уловов...

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

Учитывая, что код в первом блоке проверяет тип исключения, протестируйте базовое исключение один раз (во втором бите кода вы дважды проверяете базовое исключение), и он имеет меньшие отступы (таким образом, меньше логики для уловки) Я думаю, что первое гораздо приятнее, легче для понимания и т. д.

Недостатки: - сложнее понять

Я думаю, лучше (очень читабельно):

 try {    
   .....
 } 
 catch (IndexOutOfBoundsException iooe) {    } 
 catch (ArrayIndexOutOfBoundsException aiooe) {    }
 .....

а также

  try {
     .....
  } 
  catch (Exception e) {
     if (e instanceof Exception) {        } else 
     if (e instanceof Exception) {        } else
     .....
  }
Другие вопросы по тегам