Эффективный подход к созданию пользовательских исключений в Java

Мы использовали обработку пользовательских исключений Java в нашем коде почти для каждого стандартного отраслевого приложения. Обычный подход заключается в создании некоторых пользовательских классов исключений, расширяющих базовую лучшую практику обработки исключений, что может иметь больше смысла.

1. Традиционный подход

Предположим, что мы создаем пользовательское исключение DBException для представления исключений, которые произошли во время операций, связанных с базой данных. Традиционно мы создаем класс DBException, расширяя класс Exception.

public class DBException extends Exception {public DBException() {super();}public DBException(String message) {super(message);}public DBException(String message, Throwable cause) {super(message, cause);}}

Теперь, каждый раз, когда мы попадаем в ситуацию, когда необходимо выбросить исключение, связанное с базой данных, мы обычно создаем экземпляр DBException, помещаем некоторую информацию в виде сообщения и выбрасываем его.

Теперь давайте рассмотрим следующие выявленные нами ситуации, в которых необходимо выдавать исключение DBException:

  • Ошибка выполнения SQL
  • Нет данных, где мы ожидаем хотя бы одну строку.
  • Существует несколько строк, хотя мы ожидаем только одну строку
  • Ошибка неверных параметров
  • и еще много подобных случаев

Проблема с вышеописанным подходом заключается в том, что в блоке catch или в коде приложения, где должны обрабатываться эти исключения, DBException не предоставляет достаточно информации для индивидуальной обработки каждого из перечисленных выше вариантов использования.

2. Новый подход с использованием внутренних классов

Наш новый подход использует статические внутренние классы для каждого нового исключительного сценария.

2.1.Создание новых типов исключений

Давайте решим указанную выше проблему с помощью внутренних классов, создав по одному классу на каждый вариант использования, а затем сгруппировав их внутри класса DBException.

Начнем с класса BaseException, который создан как абстрактный и будет суперклассом всех наших классов исключений.

public abstract class BaseException extends Exception {private String message;public BaseException(String msg) {super(msg);this.message = msg;}public String getMessage() {return message;}}

Теперь пришло время создать новые внутренние классы исключений.

public class DBException {//SQL execution errorpublic static class BadExecution extends BaseException {public BadExecution(String msg) {super(msg);}}//No data exist where we expect at least one rowpublic static class NoData extends BaseException {public NoData(String msg) {super(msg);}}//Multiple rows exist where we expect only single rowpublic static class MoreData extends BaseException {public MoreData(String msg) {super(msg);}}//Invalid parameters errorpublic static class InvalidParam extends BaseException {public InvalidParam(String msg) {super(msg);}}}

Здесь мы создали внутренний класс для каждого возможного сценария ошибки, выявленного при запуске. Может быть гораздо больше дополнительных. От вас зависит только определить и добавить больше классов.

2.2 Как использовать пользовательские исключения?

Теперь, чтобы понять его полезность, давайте создадим исключение и выкинем его. Затем мы увидим сообщение об ошибке в логах.

public class TestExceptions {public static void main(String[] args){try{throw new DBExeption.NoData("No row found for id : x");}catch(Exception e){e.printStackTrace();}}}

Вывод программы:

com.exception.DBExeption$NoData: No row found for id : xat com.test.TestExceptions.main(TestExceptions.java:7)

Как вы можете видеть, сообщение журнала в трассировке стека исключений стало более информативным. Оно четко говорит, в чем заключается ошибка. В коде приложения вы также можете проверить экземпляр пользовательского исключения и обработать его соответствующим образом.

3. Преимущества

  • Главное преимущество заключается в том, что если разработчик написал какой-то сомнительный текст сообщения, то он также может четко увидеть, что на самом деле было не так.
  • Вы можете использовать сравнение экземпляров в различных ситуациях, когда имеете дело с различными исключительными сценариями.
  • Вам не нужно отправлять ни одного исключения для большого набора исключительных условий.
  • Легко писать модульные тестовые случаи для отрицательных случаев, когда вы знаете точный класс исключения, которого следует ожидать.
  • Ведение журнала стало более осмысленным и информативным.

Надеюсь, этот пост о пользовательских исключениях Java был для вас полезной информацией. Если у вас есть предложения, пожалуйста, напишите мне.

Прокрутить вверх