Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

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

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");

Ответ 2

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

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

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

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

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

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

Ответ 3

конечно, когда вы ожидаете, что сможете программно обрабатывать исключение - т.е. легко создавать отдельные инструкции 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, это исключительный случай.

Ответ 4

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

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

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

Ответ 5

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

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

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

Ответ 6

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