Возможно ли в Java улавливать два исключения в одном блоке catch?
Мне нужно уловить два исключения, потому что они требуют одинаковой логики обработки. Я хотел бы сделать что-то вроде:
catch (Exception e, ExtendsRuntimeException re) {
// common logic to handle both exceptions
}
Можно ли избежать дублирования кода обработчика в каждом блоке catch?
Ответы
Ответ 1
Java 7 и более поздние версии
Поддерживаются множественные исключения, начиная с Java 7.
Синтаксис:
try {
// stuff
} catch (Exception1 | Exception2 ex) {
// Handle both exceptions
}
Статический тип ex
является наиболее специализированным общим супертипом перечисленных исключений. Существует хорошая функция, где, если вы перебросили ex
в catch, компилятор знает, что может быть выбрано только одно из перечисленных исключений.
Java 6 и ранее
До Java 7 есть способы справиться с этой проблемой, но они, как правило, неэлегантны и имеют ограничения.
Подход № 1
try {
// stuff
} catch (Exception1 ex) {
handleException(ex);
} catch (Exception2 ex) {
handleException(ex);
}
public void handleException(SuperException ex) {
// handle exception here
}
Это становится беспорядочным, если обработчик исключений должен обращаться к локальным переменным, объявленным перед try
. И если методу обработчика необходимо перестроить исключение (и оно проверено), тогда у вас возникают серьезные проблемы с подписью. В частности, handleException
должен быть объявлен как металирование SuperException
..., что потенциально означает, что вам нужно изменить подпись входящего метода и т.д.
Подход № 2
try {
// stuff
} catch (SuperException ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
// handle exception
} else {
throw ex;
}
}
Опять же, у нас есть потенциальная проблема с сигнатурами.
Подход № 3
try {
// stuff
} catch (SuperException ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
// handle exception
}
}
Если вы оставите часть else
(например, поскольку в данный момент нет других подтипов SuperException
), код становится более хрупким. Если иерархия исключений реорганизована, этот обработчик без else
может закончиться молчащими исключениями!
Ответ 2
Java <= 6.x позволяет вам исключить только одно исключение для каждого блока catch:
try {
} catch (ExceptionType name) {
} catch (ExceptionType name) {
}
Документация:
Каждый блок catch является обработчиком исключений и обрабатывает тип исключение, указанное его аргументом. Тип аргумента, ExceptionType, объявляет тип исключения, который обработчик может обрабатывать и должен быть имя класса, наследующего класс Throwable.
Для Java 7 у вас может быть несколько исключений, обнаруженных в одном блоке catch:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
Документация:
В Java SE 7 и более поздних версиях один блок catch может обрабатывать более одного тип исключения. Эта функция может уменьшить дублирование кода и уменьшить соблазн поймать чрезмерно широкое исключение.
Справка:
http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
Ответ 3
Если вы не используете java 7, вы можете извлечь обработку исключений методу - таким образом вы можете как минимум минимизировать дублирование
try {
// try something
}
catch(ExtendsRuntimeException e) { handleError(e); }
catch(Exception e) { handleError(e); }
Ответ 4
Для Java < 7 вы можете использовать if-else вместе с Exception:
try {
// common logic to handle both exceptions
} catch (Exception ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
}
else {
throw ex;
// or if you don't want to have to declare Exception use
// throw new RuntimeException(ex);
}
}
Отредактировано и заменено Throwable with Exception.
Ответ 5
http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html охватывает множество исключений в одном блоке.
try {
// your code
} catch (Exception1 | Exception2 ex) {
// Handle 2 exceptions in Java 7
}
Я делаю учебные карты, и эта тема была полезна, просто хотела поставить мои два цента.
Ответ 6
Перед запуском Java SE 7 мы привыкли писать код с несколькими операторами catch, связанными с блоком try.
Очень простой пример:
try {
// some instructions
} catch(ATypeException e) {
} catch(BTypeException e) {
} catch(CTypeException e) {
}
Но теперь с последним обновлением на Java вместо написания нескольких операторов catch мы можем обрабатывать несколько исключений в одном объявлении catch. Вот пример, показывающий, как эта функция может быть достигнута.
try {
// some instructions
} catch(ATypeException|BTypeException|CTypeException ex) {
throw e;
}
Таким образом, множественные исключения в одном предложении catch не только упрощают код, но также уменьшают избыточность кода.
Я нашел эту статью, которая очень хорошо объясняет эту функцию вместе с ее реализацией.
Улучшена и улучшена обработка исключений из Java 7
Это также может помочь вам.