Подтвердить что ты не робот

Обработка нескольких исключений в Java

Рассмотрим следующий код Java:

try{

    // do something
    // this piece of code throws several checked exceptions.

} catch (IllegalArgumentException e) {
    handleException(e);
} catch (IllegalAccessException e) {
    handleException(e);
} catch (InvocationTargetException e) {
    handleException(e);
} catch (InstantiationException e) {
    handleException(e);
} catch (NoSuchMethodException e) {
    handleException(e);
} catch (IOException e) {
    handleException(e);
} catch (NoSuchFieldException e) {
    handleException(e);
}

Код в try блокирует несколько проверенных исключений. Все, что я хочу сделать, это зарегистрировать сообщение при возникновении исключения (с некоторыми строками сообщений). То есть моя логика обработки исключений одинакова для всех исключений.

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

Есть ли более эффективные способы обработки таких случаев?

Следующее решение не является лучшей практикой, поэтому не рекомендуется (с помощью стиля проверки).

try{
    // do something very bad
} catch (Exception e) {
    handleException(e);
} 
4b9b3361

Ответ 1

В Java 6 у вас нет выбора, более привлекательного, чем то, что вы уже предложили.

Но у Java 7 есть multi-catch выражение, которое вы можете использовать:

catch(IllegalArgumentException | IllegalAccessException | IOException exception) {
    handleException(e);
}

Ответ 2

Я чувствую, что в вашем случае второй вариант будет очень хорош. Нет необходимости слишком усложнять код, если обработка исключений одинакова для каждого случая.

Ответ 3

В Java 7 есть новое и отличное решение: вы можете написать:

try{

    // do something
    // this piece of code throws several checked exceptions.

} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
    handleException(e);
} catch ...

В более старых версиях Java ловушка общих подклассов - Exception, являющаяся одним из примеров этого - действительно неплохая идея. Нехорошо всегда делать это без учета, но это нормально, если вы подумали об этом и выбрали его как лучшее решение.

Ответ 4

Там нечего делать, с Java 6 или меньше.

С помощью java 7 вы можете сделать что-то вроде этого:

catch(InstantiationException | IOException | NoSuchFieldException exception) {
        // handle our problems here.
}

В java 6 другая "плохая практика" (но, возможно, полезная для вас) может быть:

catch (Exception e) {
   if(! e instanceof RuntimeException) // Only non-checked exceptions!
       throw e;
   handleException(e) // All checked exception.
}

Проблема: вы используете instanceof. Но ваш код выглядит лучше...

Ответ 5

Это еще один пример того, как проверенные исключения делают жизнь программистов Java жалкой. Просто потому, что часть кода может, среди прочего, выбрасывать проверенные исключения, что определенная часть кода, по всей вероятности, не, где вы хотите их обрабатывать. Если ваше приложение хорошо спроектировано, у вас уже есть центральное место, барьер исключений, где вы обрабатываете (регистрируете) свои исключения. Если это так, то вы должны просто обернуть все эти исключения в RuntimeException и передать их в сторону барьера. В этом случае это код обработки:

try {
  // do stuff
} catch (RuntimeException e) { 
  throw e; 
} catch (Exception e) { 
  throw new RuntimeException(e); 
}

Ответ 6

Что вы думаете об этом решении?

try {
    // some code that might throw an exception.
} catch (Exception e) {
    if(e instanceof RuntimeException){
        throw (RuntimeException) e;
    }
    // log exception
}

Плюсы:

  • Меньший код, может содержать логику обработки исключений для всех проверенных исключений.
  • Не обрабатывает исключения времени выполнения и ошибки. Ловит их, но бросает их обратно.

Минусы:

  • Не подтверждайте проверку лучшей практики, поскольку она все еще ловит Исключение. (но сценарии исключения прерывания времени выполнения выполняются, хотя стиль проверки может завершиться неудачей.)
  • Любые возможные побочные эффекты для downcasting для RuntimeException?

Ответ 8

Ваш код выглядит так, как будто вы сделали это:

try{
    // do something very bad
} catch (Throwable e) {
    handleException(e);
}

Это захватывает не только все исключения, но и ошибки - все, что может быть выбрано внутри блока try/catch.

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

Ваш список исключений выглядит довольно подозрительно. То есть почему вы улавливаете IllegalArgumentException, но не также NullPointerException или ClassCastException, которые семантически находятся на аналогичном уровне. И вы, кажется, используете Reflection в сочетании с IO, поэтому вам также придется иметь дело с NoClassDefFoundError, ExceptionInInitializerError и другими ошибками. А как насчет StackOverflowError или даже OutOfMemoryError...