Для обработки нескольких исключений в java мы можем:
- Использовать несколько блоков перехвата: здесь вы можете обрабатывать несколько исключений в нескольких блоках перехвата для соответствующего блока try. Поток программы будет автоматически переходить к блоку catch один за другим, а затем соответствующий блок catch будет найден в соответствии с исключением и будет обработан соответствующим образом.
- Использование нескольких операторов Catch в аргументах блока Catch. Эта функция пришла из Java 7. Здесь вы можете обрабатывать несколько исключений в одном блоке catch (разделенном вертикальной чертой) для соответствующего блока try. Поток программы автоматически перейдет к блоку catch, а затем соответствующее исключение внутри аргументов блока catch будет найдено для блока try и будет соответствующим образом обработано.
· Несколько блоков catch
∘ Зачем нужны несколько блоков catch в Java?
∘ Синтаксис
∘ Схема блока Multi-catch
∘ Примеры
· Отлов нескольких типов исключений одним обработчиком исключений
∘ Синтаксис
∘ Примеры
∘ Отлов основного исключения
· Программа
Несколько блоков catch
В Java один блок try может иметь несколько блоков catch.
Зачем нам нужно несколько блоков catch в Java?
Несколько блоков catch в Java используются для обработки разных типов исключений. Когда операторы в одном блоке try генерируют несколько исключений, нам требуется несколько блоков catch для обработки разных типов исключений. Этот механизм называется multi-catch block в java.
За блоком try может следовать один или несколько блоков catch. Каждый блок catch должен содержать отдельный обработчик исключений. Вы можете перехватывать разные исключения в разных блоках catch, если они содержат другой обработчик исключений. Когда в блоке try возникает исключение, выполняется соответствующий блок catch, который обрабатывает это конкретное исключение. Итак, если вам нужно выполнять разные задачи при возникновении разных исключений, вы можете использовать перехват нескольких попыток в Java.
Синтаксис
Синтаксис использования одной попытки с более чем одним блоком catch в java следующий:
try { statements; } catch(ExceptionType1 e1) { statements; } catch(ExceptionType2 e2) { statements; }
Блок multi-catch в Java действует как case в операторе switch. В приведенном выше синтаксисе, если объект исключения (ExceptionType1) создается блоком try, первый блок catch будет перехватывать созданный объект исключения, а оставшийся блок catch будет пропущен.
В случае, если созданный объект исключения не совпадает с первым блоком catch, второй блок catch будет проверять и так далее.
Единовременно возникает только одно исключение и одновременно выполняется только один блок catch. Все блоки catch должны быть устроены таким образом, чтобы исключение исходило из первого подкласса, а затем из суперкласса, т. е. перехват для ArithmeticException должен предшествовать перехвату для Exception.
Блок-схема блока Multi-catch
Примеры
Пример 1
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()); } } }
Вывод
/ by zero
В этом примере могут возникнуть два исключения:
- ArithmeticException, потому что мы пытаемся разделить число на 0.
- ArrayIndexOutOfBoundException, потому что мы объявили новый целочисленный массив с границами массива от 0 до 9 и пытаемся присвоить значение индексу 10.
Мы распечатываем сообщение об исключении в обоих блоках catch, то есть повторяем код.
Ассоциативность оператора присваивания = — справа налево, поэтому сначала выдается ArithmeticException с сообщением / на ноль.
Пример 2
class Example2{ public static void main(String args[]){ try{ int a[]=new int[7]; a[4]=30/0; System.out.println("First print statement in try block"); } catch(ArithmeticException e){ System.out.println("Warning: ArithmeticException"); } catch(ArrayIndexOutOfBoundsException e){ System.out.println("Warning: ArrayIndexOutOfBoundsException"); } catch(Exception e){ System.out.println("Warning: Some Other exception"); } System.out.println("Out of try-catch block..."); } }
Вывод:
Warning: ArithmeticException Out of try-catch block...
В приведенном выше примере есть несколько блоков catch, и эти блоки catch выполняются последовательно, когда в блоке try возникает исключение. Это означает, что если вы поместите последний блок catch ( catch (Exception e)) на первое место, сразу после блока try, тогда в случае любого исключения этот блок будет выполняться, поскольку он может обрабатывать все исключения. Этот блок catch следует размещать последним, чтобы избежать подобных ситуаций.
Перехват нескольких типов исключений с помощью одного обработчика исключений
В Java 7 и более поздних версиях блок catch был улучшен для обработки нескольких исключений в одном блоке catch. Если вы перехватываете несколько исключений и у них похожий код.
Один блок catch может обрабатывать (перехватывать) несколько исключений, разделяя каждое с помощью | (символ вертикальной черты) в блоке catch.
Эта функция может уменьшить дублирование кода и повысить эффективность, а также уменьшить искушение перехватить слишком широкое исключение. Байт-код, сгенерированный при компиляции этой программы, будет меньше, чем программа, содержащая несколько блоков catch, поскольку кода нет. избыточность.
Рассмотрим следующий пример, который содержит повторяющийся код в каждом из блоков catch:
catch (IOException ex) { logger.log(ex); ex.printStackTrace(); catch (SQLException ex) { logger.log(ex); ex.printStackTrace(); }
В выпусках до Java SE 7 было сложно создать общий метод для устранения дублированного кода, поскольку переменная ex
имеет разные типы.
В Java SE 7 и более поздних версиях мы можем устранить дублированный код, используя этот подход.
Синтаксис
В предложении catch
укажите типы исключений, которые может обрабатывать блок, и разделите каждый тип исключения вертикальной чертой (|
):
try { // code } catch (ExceptionType1 | Exceptiontype2 ex) { // catch block }
Символ вертикальной черты (|) может использоваться для разделения блока catch, обрабатывающего многочисленные исключения. В этом примере аргумент исключения (ex) является окончательным, то есть его нельзя изменить. Эта функция обеспечивает меньше повторений кода и меньший байтовый код.
Примеры
Пример 1
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()); } } }
Вывод
/ by zero
Перехват нескольких исключений в одном блоке catch уменьшает дублирование кода и повышает эффективность.
Байт-код, сгенерированный при компиляции этой программы, будет меньше, чем у программы с несколькими блоками catch, так как нет избыточности кода.
Примечание. Если блок catch обрабатывает несколько типов исключений, параметр catch неявно является final. В этом примере параметр catch ex является final, и поэтому вы не можете присвоить ему какие-либо значения в catch. блокировать.
Этот подход обычно используется, если вы перехватываете несколько исключений, и они имеют похожий код. но мы также можем использовать его по своему усмотрению.
Пример 2
class Main { public static void main(String[] args) { try { int array[] = new int[10]; array[10] = 30 / 0; } catch (ArithmeticException|ArrayIndexOutOfBoundsException e) { if (e instanceof ArithmeticException) System.out.println("ArithmeticException"); else System.out.println("ArrayIndexOutOfBoundsException"); } } }
Перехват базового исключения
При перехвате нескольких исключений в одном блоке catch правило обобщается до специализированного.
Это означает, что если в блоке catch есть иерархия исключений, мы можем перехватывать только базовое исключение, а не несколько специализированных исключений.
Возьмем пример.
Пример 1. Перехват только базового класса исключений
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()); } } }
Вывод
/ by zero
Мы знаем, что все классы исключений являются подклассами класса Exception. Таким образом, вместо того, чтобы перехватывать несколько специализированных исключений, мы можем просто перехватывать класс Exception.
Если базовый класс исключений уже указан в блоке catch, не используйте дочерние классы исключений в том же блоке catch. В противном случае мы получим ошибку компиляции.
Возьмем пример.
Пример 2. Перехват базовых и дочерних классов исключений
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: error: Alternatives in a multi-catch statement cannot be related by subclassing
В этом примере ArithmeticException и ArrayIndexOutOfBoundException являются подклассами класса Exception. Итак, мы получаем ошибку компиляции.
Программа
В некоторых случаях одним фрагментом кода может быть вызвано более одного исключения. Чтобы справиться с ситуацией такого типа, вы можете указать два или более предложения catch, каждое из которых будет перехватывать разные типы исключений. При возникновении исключения каждый оператор catch проверяется по порядку, и выполняется первый оператор, тип которого совпадает с типом исключения. После выполнения одного оператора catch другие игнорируются, и выполнение продолжается после блока try/catch. В следующем примере перехватываются два разных типа исключений:
// Demonstrate multiple catch statements. class MultiCatch { public static void main(String args[]) { try { int a = args.length; System.out.println("a = " + a); int b = 42 / a; int c[] = { 1 }; c[42] = 99; } catch(ArithmeticException e) { System.out.println("Divide by 0: " + e); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("Array index oob: " + e); } System.out.println("After try/catch blocks."); } }
Эта программа вызовет исключение деления на ноль, если она будет запущена без аргументов командной строки, поскольку a будет равно нулю. Он переживет деление, если вы предоставите аргумент командной строки, установив значение a больше нуля. Но это вызовет ArrayIndexOutOfBoundsException, поскольку массив int c имеет длину 1, а программа пытается присвоить значение c[42].
Вот результат, полученный при запуске в обоих направлениях:
C:\>java MultiCatch a = 0 Divide by 0: java.lang.ArithmeticException: / by zero After try/catch blocks. C:\>java MultiCatch TestArg a = 1 Array index oob: java.lang.ArrayIndexOutOfBoundsException:42 After try/catch blocks.
Когда вы используете несколько операторов catch, важно помнить, что подклассы исключений должны предшествовать любому из своих суперклассов. Это связано с тем, что оператор catch, использующий суперкласс, будет перехватывать исключения этого типа, а также любые его подклассы. Таким образом, подкласс никогда не будет достигнут, если он будет следовать за суперклассом. Кроме того, в Java недостижимый код является ошибкой. Например, рассмотрим следующую программу:
/* This program contains an error. A subclass must come before its superclass in a series of catch statements. If not, unreachable code will be created and a compile-time error will result. */ class SuperSubCatch { public static void main(String args[]) { try { int a = 0; int b = 42 / a; } catch(Exception e) { System.out.println("Generic Exception catch."); } /* This catch is never reached because ArithmeticException is a subclass of Exception. */ catch(ArithmeticException e) { // ERROR - unreachable System.out.println("This is never reached."); } } }
Если вы попытаетесь скомпилировать эту программу, вы получите сообщение об ошибке, в котором говорится, что второй оператор catch недоступен, поскольку исключение уже было перехвачено. Поскольку ArithmeticException является подклассом Exception, первый оператор catch будет обрабатывать все ошибки, связанные с Exception, включая ArithmeticException. Это означает, что второй оператор catch никогда не будет выполняться. Чтобы решить эту проблему, измените порядок операторов catch.
Присоединяйтесь к группе Mouad Oumous Java WhatsApp JOIN
Присоединяйтесь к Telegram-каналу Mouad Oumous JOIN