Автор оригинала: Shubham Aggarwal.
1. Обзор
В этой статье мы очень кратко рассмотрим, что такое Exception , и подробно обсудим цепные исключения в Java.
Проще говоря, исключение – это событие, которое нарушает нормальный ход выполнения программы. Давайте теперь посмотрим, как именно мы можем связать исключения в цепочку, чтобы получить из них лучшую семантику.
2. Цепные Исключения
Цепочка Исключение помогает определить ситуацию, в которой одно исключение вызывает другое Исключение в приложении.
Например, рассмотрим метод, который вызывает исключение ArithmeticException из-за попытки деления на ноль, но фактической причиной исключения была ошибка ввода-вывода, из-за которой делитель был равен нулю.Метод вызовет ArithmeticException вызывающему объекту. Вызывающий абонент не будет знать о фактической причине Исключения . В таких ситуациях используется цепочка Исключение .
Эта концепция была введена в JDK 1.4.
Давайте посмотрим, как цепные исключения поддерживаются в Java.
3. Бросаемый класс
Класс Throwable имеет некоторые конструкторы и методы для поддержки цепных исключений. Во-первых, давайте посмотрим на конструкторов.
- Throwable(Throwable cause) – Throwable имеет один параметр, который указывает фактическую причину Исключения .
- Throwable(String desc, Throwable cause) – этот конструктор также принимает описание Исключения с фактической причиной Исключения .
Далее давайте рассмотрим методы, предоставляемые этим классом:
- getCause() метод – Этот метод возвращает фактическую причину, связанную с текущим Исключением .
- initCause() метод – Он устанавливает основную причину с вызовом Исключения .
4. Пример
Теперь давайте рассмотрим пример, в котором мы установим ваше собственное описание Exception и создадим цепочку Exception :
public class MyChainedException { public void main(String[] args) { try { throw new ArithmeticException("Top Level Exception.") .initCause(new IOException("IO cause.")); } catch(ArithmeticException ae) { System.out.println("Caught : " + ae); System.out.println("Actual cause: "+ ae.getCause()); } } }
Как и предполагалось, это приведет к:
Caught: java.lang.ArithmeticException: Top Level Exception. Actual cause: java.io.IOException: IO cause.
5. Почему Цепные Исключения?
Нам нужно связать исключения в цепочку, чтобы сделать журналы читаемыми. Давайте напишем два примера. Во-первых, без цепочек исключений, а во-вторых, с цепочками исключений. Позже мы сравним, как ведут себя журналы в обоих случаях.
Для начала мы создадим ряд исключений:
class NoLeaveGrantedException extends Exception { public NoLeaveGrantedException(String message, Throwable cause) { super(message, cause); } public NoLeaveGrantedException(String message) { super(message); } } class TeamLeadUpsetException extends Exception { // Both Constructors }
Теперь давайте начнем использовать приведенные выше исключения в примерах кода.
5.1. Без Цепей
Давайте напишем пример программы, не меняя наши пользовательские исключения.
public class MainClass { public void main(String[] args) throws Exception { getLeave(); } void getLeave() throws NoLeaveGrantedException { try { howIsTeamLead(); } catch (TeamLeadUpsetException e) { e.printStackTrace(); throw new NoLeaveGrantedException("Leave not sanctioned."); } } void howIsTeamLead() throws TeamLeadUpsetException { throw new TeamLeadUpsetException("Team Lead Upset"); } }
В приведенном выше примере журналы будут выглядеть следующим образом:
com.baeldung.chainedexception.exceptions.TeamLeadUpsetException: Team lead Upset at com.baeldung.chainedexception.exceptions.MainClass .howIsTeamLead(MainClass.java:46) at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:34) at com.baeldung.chainedexception.exceptions.MainClass .main(MainClass.java:29) Exception in thread "main" com.baeldung.chainedexception.exceptions. NoLeaveGrantedException: Leave not sanctioned. at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:37) at com.baeldung.chainedexception.exceptions.MainClass .main(MainClass.java:29)
5.2. С Цепью
Далее, давайте напишем пример с цепочкой наших пользовательских исключений:
public class MainClass { public void main(String[] args) throws Exception { getLeave(); } public getLeave() throws NoLeaveGrantedException { try { howIsTeamLead(); } catch (TeamLeadUpsetException e) { throw new NoLeaveGrantedException("Leave not sanctioned.", e); } } public void howIsTeamLead() throws TeamLeadUpsetException { throw new TeamLeadUpsetException("Team lead Upset."); } }
Наконец, давайте посмотрим на журналы, полученные с помощью цепных исключений:
Exception in thread "main" com.baeldung.chainedexception.exceptions .NoLeaveGrantedException: Leave not sanctioned. at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:36) at com.baeldung.chainedexception.exceptions.MainClass .main(MainClass.java:29) Caused by: com.baeldung.chainedexception.exceptions .TeamLeadUpsetException: Team lead Upset. at com.baeldung.chainedexception.exceptions.MainClass .howIsTeamLead(MainClass.java:44) at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:34) ... 1 more
Мы можем легко сравнить показанные журналы и сделать вывод, что цепные исключения приводят к более чистым журналам.
В этой статье мы рассмотрели концепцию цепных исключений.
Реализацию всех примеров можно найти в проекте Github – это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.