Возможно ли в 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 Это также может помочь вам.