8

Можно ли перехватить несколько исключений Java в одном блоке catch?

10

Я хочу поймать несколько исключений одновременно в Java. У меня есть следующий код:

try {
    ...     
} catch (/* код для обработки IllegalArgumentException, SecurityException, 
            IllegalAccessException и NoSuchFieldException одновременно */) {
    someCode();
}

Вместо того, чтобы писать:

try {
    ...     
} catch (IllegalArgumentException e) {
    someCode();
} catch (SecurityException e) {
    someCode();
} catch (IllegalAccessException e) {
    someCode();
} catch (NoSuchFieldException e) {
    someCode();
}

Есть ли способ сделать это?

5 ответ(ов)

1

Не совсем до Java 7, но я бы сделал что-то вроде этого:

Java 6 и ниже:

try {
  //.....
} catch (Exception exc) {
  if (exc instanceof IllegalArgumentException || exc instanceof SecurityException || 
      exc instanceof IllegalAccessException || exc instanceof NoSuchFieldException) {
    
     someCode();

  } else if (exc instanceof RuntimeException) {
     throw (RuntimeException) exc;     

  } else {
    throw new RuntimeException(exc);
  }
}

Java 7:

try {
  //.....
} catch (IllegalArgumentException | SecurityException |
         IllegalAccessException | NoSuchFieldException exc) {
  someCode();
}

В Java 7 введена возможность обработки нескольких исключений в одном блоке catch, что делает код более читаемым и компактным.

0

Нет, одно исключение на клиента до Java 7.

Вы можете перехватить суперкласс, такой как java.lang.Exception, если при этом выполняете одно и то же действие во всех случаях.

try {
    // какой-то код
} catch(Exception e) { // Все исключения обрабатываются здесь, так как они все наследуются от java.lang.Exception
    e.printStackTrace();
}

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

С JDK 7 и новее вы можете сделать так:

try {
    ...     
} catch (IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e) {
    someCode();
}
0

В Java 7 вы можете определять несколько блоков catch для обработки различных исключений в одном блоке. Например, вы можете написать так:

catch (IllegalArgumentException | SecurityException e)
{
    ...
}

Таким образом, если выбрасывается исключение IllegalArgumentException или SecurityException, будет выполнен один и тот же блок кода для обработки этих исключений. Это упрощает код и делает его более читаемым, так как вам не нужно дублировать одну и ту же логику обработки исключений для разных типов исключений.

0

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

try {
   ...
} catch (Exception e) {
   someCode();
}

В более распространённом случае, если RepositoryException — это базовый класс, а PathNotFoundException — производный класс, то код будет выглядеть так:

try {
   ...
} catch (RepositoryException re) {
   someCode();
} catch (Exception e) {
   someCode();
}

В этом примере код поймает как RepositoryException, так и PathNotFoundException для одной группы обработки исключений, а все остальные исключения будут объединены в другую.

С версии Java 7, в соответствии с ответом @OscarRyz выше, вы можете использовать множественный ловец исключений:

try { 
  ...
} catch( IOException | SQLException ex ) { 
  ...
}

Таким образом, вы можете обрабатывать несколько исключений в одном блоке catch, что делает код более чистым и читаемым.

0

Чистый (но менее многословный и, возможно, не столь предпочтительный) вариант ответа пользователя user454322 на вопрос о Java 6 (т.е. Android) заключается в том, чтобы поймать все исключения (Exception) и повторно выбросить исключения времени выполнения (RuntimeException). Это решение не сработает, если вы планируете обрабатывать другие типы исключений выше в стеке (если только вы также не будете их повторно выбрасывать), но оно эффективно ловит все проверяемые исключения.

Например:

try {
    // КОД, КОТОРЫЙ ВЫБРАСЫВАЕТ ИСКЛЮЧЕНИЕ
} catch (Exception e) {
    if (e instanceof RuntimeException) {
        // это исключение было неожиданным, поэтому выбрасываем его повторно
        throw e;
    } else {
        // ВАШ КОД ДЛЯ ВСЕХ ПРОВЕРЯЕМЫХ ИСКЛЮЧЕНИЙ
    } 
}

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь