Когда мы должны создавать собственные классы исключений Java?

260
23

с хорошей проектной/практической точки зрения, когда мы должны создавать и использовать пользовательские классы исключений Java, а не те, которые уже предопределены в java?


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


Какова наилучшая практика?


Спасибо!

спросил(а) 2021-01-19T20:38:22+03:00 9 месяцев назад
1
Решение
257

Из передовой практики обработки исключений:

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

Что не так в следующем коде?

public class DuplicateUsernameException extends Exception {}

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

Мы могли бы добавить полезные методы к DuplicateUsernameException, например:

public class DuplicateUsernameException
extends Exception {
public DuplicateUsernameException
(String username){....}
public String requestedUsername(){...}
public String[] availableNames(){...}
}

Новая версия предоставляет два полезных метода: requestedUsername(), который возвращает запрашиваемое имя и availableNames(), который возвращает массив доступных имен пользователей, подобных запрошенному. Клиент может использовать эти методы, чтобы сообщить, что запрошенное имя пользователя недоступно, и что доступны другие имена пользователей. Но если вы не собираетесь добавлять дополнительную информацию, просто введите стандартное исключение:

throw new IllegalArgumentException("Username already taken");

ответил(а) 2021-01-19T20:38:22+03:00 9 месяцев назад
144

с хорошей проектной/практической точки зрения, когда мы должны создавать и использовать пользовательские классы исключений Java, а не те, которые уже предопределены в java?



Если существующие имена исключений не покрывают ваши потребности.


Еще одна проблема дизайна заключается в расширении "хорошего" класса исключений; например, если вы создаете исключение, связанное с I/O, вы должны идеально наследовать IOException; если исключение указывает на ошибку программиста, вы должны наследовать RuntimeException (т.е. сделать исключение исключенным).

Повышение пользовательских исключений также позволяет более точно обрабатывать исключения; например, если вы определили FooException наследующий IOException, то вы можете иметь специальное лечение для него:


try { ... }
catch (FooException e) { ... } // Catch it _before_ IOException!
catch (IOException e) { ... }

Кроме того, исключения - это классы, подобные любым другим, поэтому вы можете добавлять собственные методы и т.д.; например, Джексон определяет JsonProcessingException, который наследует IOException. Если вы его поймаете, вы можете получить информацию о местоположении ошибки синтаксического анализа, используя .getLocation().

ответил(а) 2021-01-19T20:38:22+03:00 9 месяцев назад
113

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


try{    
buyWidgets();
}
catch(AuthenticationException ex)
{
promptForLogin();
}
catch(InsufficientFundsException ex)
{
promptToRefillAccount();
}
//let other types of exceptions to propagate up the call stack

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


В то время как исключения более дорогостоящие CPU, чем операторы if-else (в основном из-за затрат на построение трассировки стека), стоимость является относительной и должна оцениваться в контексте конкретного варианта использования. Не каждый фрагмент кода должен быть быстро масштабируемым, и некоторые люди считают, что условия для чтения и тестирования более громоздки. Например, почти все менеджеры транзакций реализуют идиомы commit-rollback-retry с использованием исключений. (Попробуйте записать аспект повторной транзакции, не вылавливая исключения)


Отдельно следует придерживаться принципа разделения интересов: не каждый фрагмент кода должен иметь дело со всеми возможными условиями. Независимо от того, не входит ли в систему при покупке виджета, исключительный случай действительно зависит от приложения и конкретного места в базе кода приложения. Например, у вас может быть Служба с операциями для зарегистрированных пользователей. Для методов в этой службе нет смысла обрабатывать аутентификацию - вместо этого эти методы ожидали бы, что код ранее в цепочке вызовов будет гарантировать, что пользователь аутентифицирован, и, таким образом, просто бросать исключения, если это не так. Таким образом, для тех методов, которые не регистрируются в IS, это исключительный случай.

ответил(а) 2021-01-19T20:38:22+03:00 9 месяцев назад
46

Я часто создаю пользовательские исключения, если есть больше информации, которую мне нужно передать вместо сообщения об ошибке.


Например, конкретные коды ошибок или фактические или ожидаемые значения. они также могут иметь свои собственные геттеры, чтобы вы могли запрограммировать эти поля без необходимости синтаксического анализа сообщения String, которое могло бы сломаться, если вы когда-либо измените текст сообщения. (Или перевести его на другой язык)


Если вы сделаете свои собственные исключения, я бы рекомендовал расширить распространенные исключения JDK, чтобы ваш API мог сказать throws IOException, но он действительно бросает MycustomIOException. таким образом, пользователи вашего API не должны знать о своих собственных версиях, если они этого не хотят.

ответил(а) 2021-01-19T20:38:22+03:00 9 месяцев назад
47

Вы делаете это, когда используете свое собственное исключение, добавляет ценность вашей базе кода.

Это так просто. Значение может быть:

    улов на более высоком уровне может быть проще, например, когда все ваши исключения имеют общий базовый тип ваше исключение содержит данные о добавлении (мы включаем ключи NLS в наши собственные исключения, так что более высокий уровень знает, как отправлять сообщения пользователям, принимающим I18N)

ответил(а) 2021-01-19T20:38:22+03:00 9 месяцев назад
46

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

ответил(а) 2021-01-19T20:38:22+03:00 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема