Обработка исключений
В теме Введение в обработку исключений были рассмотрены некоторые основные моменты обработки исключений. Сейчас более подробно поговорим о других моментах, связанных с обработкой исключений.
Оператор throws
Иногда метод, в котором может генерироваться исключение, сам не обрабатывает это исключение. В этом случае в объявлении метода используется оператор throws , который надо обработать при вызове этого метода. Например, у нас имеется метод вычисления факториала, и нам надо обработать ситуацию, если в метод передается число меньше 1:
public static int getFactorial(int num) throws Exception < if(num<1) throw new Exception("The number is less than 1"); int result=1; for(int i=1; i<=num;i++)< result*=i; >return result; >
С помощью оператора throw по условию выбрасывается исключение. В то же время метод сам это исключение не обрабатывает с помощью try..catch, поэтому в определении метода используется выражение throws Exception .
Теперь при вызове этого метода нам обязательно надо обработать выбрасываемое исключение:
public static void main(String[] args) < try< int result = getFactorial(-6); System.out.println(result); >catch(Exception ex) < System.out.println(ex.getMessage()); >>
Без обработки исключение у нас возникнет ошибка компиляции, и мы не сможем скомпилировать программу.
В качестве альтернативы мы могли бы и не использовать оператор throws, а обработать исключение прямо в методе:
public static int getFactorial(int num) < int result=1; try< if(num<1) throw new Exception("The number is less than 1"); for(int i=1; i<=num;i++)< result*=i; >> catch(Exception ex) < System.out.println(ex.getMessage()); result=num; >return result; >
Как бросить исключение java
Для бросания исключения в Java нужно использовать оператор throw . Он позволяет явно сгенерировать исключение в любом месте кода.
public void divide(int a, int b) throws ArithmeticException if (b == 0) throw new ArithmeticException("Деление на ноль"); > int result = a / b; System.out.println("Результат: " + result); >
В этом примере мы проверяем, равен ли делитель b нулю, и если да, то мы бросаем новое исключение типа ArithmeticException с сообщением «Деление на ноль».
Когда исключение брошено, код в методе останавливается, и контроль передается обработчику исключений или вызывающему методу, который должен перехватить и обработать исключение.
Собственные исключения в Java: как управлять ошибками в вашем приложении
Исключения являются важной частью любой программы, позволяя элегантно обрабатывать ошибки и исключительные ситуации. В Java, помимо стандартных исключений, разработчики также могут создавать собственные исключения, которые отражают специфические ситуации в их приложениях или библиотеках. В этой статье мы рассмотрим, для чего нужны собственные исключения в Java и как их использовать.
Статья может быть полезна для новичков или тем, кто не так давно в мире Java. В ней мы не касаемся типов исключений, а рассматриваем создание собственных.
Зачем нужны собственные исключения?
Этот вопрос может возникнуть у тех кто только входит в ИТ, и вопрос даже вполне корректный, ведь имеется масса своих исключений, но собственные исключения позволяют разработчикам более гибко управлять ошибками и обрабатывать их в соответствии с требованиями конкретного приложения. Вот несколько причин, по которым собственные исключения в Java могут быть полезны:
1. Отражение специфических ситуаций: Собственные исключения могут быть созданы для отображения конкретных ошибок или ситуаций, которые могут возникнуть в приложении. Например, вы можете создать исключение InvalidInputException , чтобы указать, что получен недопустимый ввод от пользователя.
2. Локализация и обработка ошибок: Собственные исключения позволяют локализовать и обрабатывать ошибки на определенном уровне в коде. Каждое исключение может быть обработано отдельно, что упрощает отладку и обработку ошибок.
3. Гибкая обработка и восстановление: При использовании собственных исключений вы можете предоставить гибкую обработку ошибок, включая восстановление после ошибки или выполнение альтернативных действий. Например, вы можете перехватить исключение FileNotFoundException и попробовать открыть альтернативный файл.
4. Инкапсуляция ошибок: Собственные исключения позволяют инкапсулировать информацию об ошибке и передавать ее на более высокий уровень в коде. Это помогает упростить код и улучшить его читаемость, так как обработка ошибок может быть сосредоточена в одном месте.
5. Расширение стандартных исключений: Собственные исключения могут расширять стандартные исключения Java, такие как Exception или RuntimeException , чтобы добавить дополнительную информацию или функциональность при обработке ошибок. Например, вы можете создать исключение DatabaseException , которое расширяет Exception и содержит дополнительные методы для работы с базой данных.
Примеры создания собственных исключений
Пример 1
Для создания собственного исключения в Java необходимо создать класс, который расширяет стандартный класс исключений или другое собственное исключение.
public class InvalidInputException extends Exception < public InvalidInputException(String message) < super(message); >>
В этом примере класс InvalidInputException расширяет класс Exception и имеет конструктор, который принимает сообщение об ошибке в качестве параметра. В конструкторе вызывается конструктор суперкласса Exception , передавая ему сообщение.
Теперь, когда у вас есть собственное исключение, вы можете использовать его в своем коде для обработки конкретных ошибок.
public class Example < public static void main(String[] args) < try < validateInput("abc"); >catch (InvalidInputException e) < System.out.println("Invalid input: " + e.getMessage()); >> public static void validateInput(String input) throws InvalidInputException < if (input == null || input.isEmpty()) < throw new InvalidInputException("Input cannot be null or empty"); >> >
В этом примере метод validateInput() проверяет, является ли входная строка пустой или равной null . Если это так, то метод выбрасывает исключение InvalidInputException с сообщением. В методе main() мы вызываем validateInput() с недопустимым вводом и перехватываем исключение с помощью блока catch , где выводим сообщение об ошибке.
Пример 2
// Создаем собственное исключение class CustomException extends Exception < public CustomException(String message) < super(message); >> // Класс, который использует собственное исключение class Example < // Метод, который может выбросить собственное исключение public static void doSomething(int value) throws CustomException < if (value < 0) < throw new CustomException("Значение должно быть больше или равно нулю"); >> public static void main(String[] args) < try < // Вызываем метод, который может выбросить исключение doSomething(-5); >catch (CustomException e) < // Обрабатываем исключение System.out.println("Ошибка: " + e.getMessage()); >> >
В этом примере у нас есть метод doSomething , который может выбросить собственное исключение CustomException , если значение аргумента меньше нуля. В методе main мы вызываем этот метод с отрицательным значением и перехватываем исключение с помощью блока catch . Затем мы выводим сообщение об ошибке.
Этот пример показывает, как правильно объявлять методы, которые могут выбрасывать собственные исключения, и как перехватывать их при вызове этих методов
Пример 3
// Создаем собственное исключение class InvalidEmailException extends Exception < public InvalidEmailException(String message) < super(message); >> // Класс, который использует собственное исключение class EmailValidator < // Метод, который может выбросить собственное исключение public static void validateEmail(String email) throws InvalidEmailException < if (!email.contains("@")) < throw new InvalidEmailException("Некорректный адрес электронной почты"); >> public static void main(String[] args) < try < // Вызываем метод, который может выбросить исключение validateEmail("example.com"); >catch (InvalidEmailException e) < // Обрабатываем исключение System.out.println("Ошибка: " + e.getMessage()); >> >
В этом примере у нас есть метод validateEmail , который может выбросить собственное исключение InvalidEmailException , если переданный адрес электронной почты не содержит символа «@». В конструкторе исключения мы передаем сообщение об ошибке. В методе main мы вызываем этот метод с некорректным адресом электронной почты и перехватываем исключение с помощью блока catch . Затем мы выводим сообщение об ошибке.
Вот вроде бы и все, достаточно легко и просто, как всегда, есть одно большое но! можно создать исключения, которые только усложнят жизнь разработку
Пример 4 (некорректное создание исключений)
// Некорректное создание собственного исключения class MyException extends Exception < public MyException() < super(); >>
В этом примере мы создаем собственное исключение MyException , но не передаем ему сообщение об ошибке через конструктор. Это может привести к непонятным или неинформативным сообщениям об ошибках при перехвате исключения.
Корректным подходом будет передача сообщения об ошибке через конструктор, как показано в предыдущем примере:
class MyException extends Exception < public MyException(String message) < super(message); >>
Таким образом, при выбрасывании и перехвате исключения MyException будет доступно информативное сообщение об ошибке.
Пример 5 (некорректное использование)
Примером неправильного использования собственного исключения может быть его применение без реальной необходимости или создание избыточных иерархий исключений.
public class MyCustomException extends Exception < // . >public class Example < public static void main(String[] args) < try < throw new MyCustomException(); >catch (MyCustomException e) < System.out.println("Caught MyCustomException"); >catch (Exception e) < System.out.println("Caught Exception"); >> >
В этом примере мы создаем собственное исключение MyCustomException , но в блоке catch обрабатываем его так же, как и любое другое исключение Exception . Такое использование собственного исключения делает его бессмысленным, поскольку нет никакой разницы между обработкой MyCustomException и обработкой любого другого исключения.
Инструмент создания собственных исключений может иметь как плюсы, так и минусы, поэтому подход к его использованию должен быть обоснован архитектурой кода.
Плюсы создания собственных исключений:
1. Отражение специфических ситуаций: Собственные исключения позволяют точно отражать конкретные ошибки или ситуации, которые могут возникнуть в вашем приложении. Это упрощает понимание и обработку ошибок другими разработчиками, которые работают с вашим кодом.
2. Гибкая обработка и восстановление: Использование собственных исключений позволяет предоставить гибкую обработку ошибок, включая восстановление после ошибки или выполнение альтернативных действий. Это помогает повысить надежность и стабильность вашего приложения.
3. Инкапсуляция информации об ошибке: Собственные исключения позволяют инкапсулировать информацию об ошибке, включая дополнительные детали или контекст ошибки. Это помогает упростить код и улучшить его читаемость, так как обработка ошибок может быть сосредоточена в одном месте.
4. Расширение стандартных исключений: Вы можете расширять стандартные исключения Java, такие как Exception или RuntimeException , с добавлением дополнительной функциональности или информации для обработки ошибок. Это позволяет вам более точно определить тип ошибки и предоставить дополнительные методы для работы с ней.
Минусы создания собственных исключений:
1. Усложнение кода: Создание собственных исключений может привести к усложнению кода, особенно если их необходимо обрабатывать на разных уровнях в приложении. Слишком много разных исключений может сделать код сложным для чтения и понимания.
2. Переусиление иерархии исключений: Если неправильно спроектировать иерархию собственных исключений, это может привести к избыточности или неправильной обработке ошибок. Следует тщательно продумать, какие исключения создавать и как они связаны между собой.
3. Неоднозначность исключений: Если вы создаете собственные исключения, которые перекрывают или имеют схожие имена с существующими стандартными исключениями, это может вызывать путаницу при обработке ошибок. Разработчики могут испытывать трудности в определении, какое исключение выбрать для обработки конкретной ситуации.
4. Проблемы совместимости: Если вы используете собственные исключения в библиотеке или API, это может создать проблемы совместимости, если другие разработчики не знакомы с вашими исключениями или не знают, как с ними работать.
Заключение
Собственные исключения в Java предоставляют разработчикам возможность более гибко управлять ошибками и исключительными ситуациями в своих приложениях или библиотеках. Они позволяют отразить специфические ситуации, локализовать и обработать ошибки, предоставить гибкую обработку и восстановление, инкапсулировать ошибки и расширить стандартные исключения.
Исключения в Java. Часть 2
Учимся футболить исключения и исследуем их различия на практике.

Иллюстрация: Dana Moskvina / Skillbox Media

Мария Помазкина
Хлебом не корми — дай кому-нибудь про Java рассказать.
Из этой статьи вы узнаете:
- как пробросить исключение наверх;
- когда и зачем это делать;
- о checked- и unchecked-исключениях;
- о хоткеях, ускоряющих обработку исключений.
Проброс исключений
Ранее мы рассказали, что все исключения в Java — это классы, наследники Throwable и Exception; мельком взглянули на класс Error, от которого наследуются ошибки уровня Java-машины.

Сегодня поговорим только про семейство Exception.
В Java много встроенных исключений. На каждом останавливаться не будем: вы и так познакомитесь с ними на практике. Сейчас важнее до конца уяснить, как с исключениями работать.
Напомню, что есть три способа обойтись с исключением:
- Ничего не делать.
- Обработать в конструкции try-catch.
- Пробросить наверх.
С первыми двумя мы разбирались здесь. Остался проброс исключений наверх.
Наверх — это куда? Это выше по стеку вызовов. То есть если метод A вызвал метод B, метод B вызвал метод C, а методC пробросил исключение наверх, то оно всплывёт до метода B — и станет его проблемой.
Как пробросить исключение?
Вернёмся к примеру из предыдущей статьи. Помните, там был метод hereWillBeTrouble, который мог вызвать исключение ArithmeticException?
Чтобы пробросить это исключение, достаточно добавить в сигнатуру метода hereWillBeTrouble ключевое слово throws, а после него — название класса пробрасываемого исключения.

Исключение передалось как эстафетная палочка. И теперь источником исключения является не только строка int oops = 42 / 0, но и строка hereWillBeTrouble();.
Что нам дал проброс исключения?

- Так мы говорим разработчику, который вызывает метод hereWillBeTrouble, что в нём может возникнуть исключение типа ArithmeticException.
- В вызывающем метод hereWillBeTrouble коде это исключение можно обработать с помощью конструкции try-catch.

Что дальше?
В следующей статье я расскажу обо всей мощи конструкции try-catch.
Ещё больше хитростей, дженериков и других особенностей Java — на курсе «Профессия Java-разработчик». Научим программировать на самом востребованном языке и поможем устроиться на работу.
