Можно ли перехватить несколько исключений Java в одном блоке catch?
Я хочу поймать несколько исключений одновременно в 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 ответ(ов)
Не совсем до 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
, что делает код более читаемым и компактным.
Нет, одно исключение на клиента до Java 7.
Вы можете перехватить суперкласс, такой как java.lang.Exception, если при этом выполняете одно и то же действие во всех случаях.
try {
// какой-то код
} catch(Exception e) { // Все исключения обрабатываются здесь, так как они все наследуются от java.lang.Exception
e.printStackTrace();
}
Но это может быть не лучшей практикой. Вы должны перехватывать исключение только в том случае, если у вас есть стратегия для его обработки — а логгирование и повторное выбрасывание не являются "обработкой". Если у вас нет корректирующих действий, лучше добавить исключение в сигнатуру метода и позволить ему "подняться" к тому, кто сможет обработать ситуацию.
С JDK 7 и новее вы можете сделать так:
try {
...
} catch (IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e) {
someCode();
}
В Java 7 вы можете определять несколько блоков catch
для обработки различных исключений в одном блоке. Например, вы можете написать так:
catch (IllegalArgumentException | SecurityException e)
{
...
}
Таким образом, если выбрасывается исключение IllegalArgumentException
или SecurityException
, будет выполнен один и тот же блок кода для обработки этих исключений. Это упрощает код и делает его более читаемым, так как вам не нужно дублировать одну и ту же логику обработки исключений для разных типов исключений.
Если у вас есть иерархия исключений, вы можете использовать базовый класс для перехвата всех подклассов исключений. В предельном случае вы можете поймать все исключения 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
, что делает код более чистым и читаемым.
Чистый (но менее многословный и, возможно, не столь предпочтительный) вариант ответа пользователя user454322 на вопрос о Java 6 (т.е. Android) заключается в том, чтобы поймать все исключения (Exception
) и повторно выбросить исключения времени выполнения (RuntimeException
). Это решение не сработает, если вы планируете обрабатывать другие типы исключений выше в стеке (если только вы также не будете их повторно выбрасывать), но оно эффективно ловит все проверяемые исключения.
Например:
try {
// КОД, КОТОРЫЙ ВЫБРАСЫВАЕТ ИСКЛЮЧЕНИЕ
} catch (Exception e) {
if (e instanceof RuntimeException) {
// это исключение было неожиданным, поэтому выбрасываем его повторно
throw e;
} else {
// ВАШ КОД ДЛЯ ВСЕХ ПРОВЕРЯЕМЫХ ИСКЛЮЧЕНИЙ
}
}
Тем не менее, если говорить о многословии, возможно, лучше установить булевую переменную или какую-то другую переменную и на основе этого выполнить некоторый код после блока try-catch.
Как проверить, что в JUnit-тестах выбрасывается определенное исключение?
Поймать и вывести полный трейсбек исключения в Python без остановки/выхода из программы
Как установить Java 8 на Mac
Почему в RecyclerView отсутствует onItemClickListener()?
Что значит 'synchronized'?