В этом руководстве мы научимся обрабатывать несколько исключений в Java с помощью примеров.
До Java 7 нам приходилось писать несколько кодов обработки исключений для разных типов исключений, даже при наличии избыточности кода.
Возьмем пример.
Пример 1: несколько блоков catch
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (ArithmeticException e) ( System.out.println(e.getMessage()); ) catch (ArrayIndexOutOfBoundsException e) ( System.out.println(e.getMessage()); ) ) )
Вывод
/ по нулю
В этом примере могут возникнуть два исключения:
ArithmeticException
потому что мы пытаемся разделить число на 0.ArrayIndexOutOfBoundsException
потому что мы объявили новый целочисленный массив с границами массива от 0 до 9 и пытаемся присвоить значение индексу 10.
Мы печатаем сообщение об исключении в обоих catch
блоках, т.е. дублирующийся код.
Ассоциативность оператора присваивания =
- справа налево, поэтому ArithmeticException
первым с сообщением / передается объект an с помощью нуля.
Обработка множественных исключений в блоке catch
В Java SE 7 и более поздних версиях мы теперь можем ловить более одного типа исключений в одном catch
блоке.
Каждый тип исключения, который может обрабатываться catch
блоком, отделяется вертикальной чертой или вертикальной чертой |
.
Его синтаксис:
try ( // code ) catch (ExceptionType1 | Exceptiontype2 ex) ( // catch block )
Пример 2: блок с несколькими захватами
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (ArithmeticException | ArrayIndexOutOfBoundsException e) ( System.out.println(e.getMessage()); ) ) )
Вывод
/ по нулю
Перехват нескольких исключений в одном catch
блоке снижает дублирование кода и повышает эффективность.
Байт-код, сгенерированный при компиляции этой программы, будет меньше, чем программа, имеющая несколько catch
блоков, так как нет избыточности кода.
Примечание. Если catch
блок обрабатывает несколько исключений, параметр catch неявно final
. Это означает, что мы не можем присвоить какие-либо значения параметрам catch.
Исключение базы ловли
При отлове нескольких исключений в одном catch
блоке правило обобщается до специализированного.
Это означает, что если в catch
блоке есть иерархия исключений , мы можем поймать только базовое исключение, а не несколько специализированных исключений.
Возьмем пример.
Пример 3: перехват только базового класса исключения
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (Exception e) ( System.out.println(e.getMessage()); ) ) )
Вывод
/ по нулю
Мы знаем, что все классы исключений являются подклассами Exception
класса. Итак, вместо того, чтобы перехватывать несколько специализированных исключений, мы можем просто перехватить Exception
класс.
Если базовый класс исключения уже был указан в catch
блоке, не используйте дочерние классы исключений в том же catch
блоке. В противном случае мы получим ошибку компиляции.
Возьмем пример.
Пример 4: перехват базовых и дочерних классов исключений
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (Exception | ArithmeticException | ArrayIndexOutOfBoundsException e) ( System.out.println(e.getMessage()); ) ) )
Вывод
Main.java:6: ошибка: альтернативы в операторе multi-catch не могут быть связаны с помощью подкласса
В этом примере ArithmeticException
и ArrayIndexOutOfBoundsException
являются подклассами Exception
класса. Итак, получаем ошибку компиляции.