Каково общее правило thumbs для создания исключения в Java?

StackOverflow https://stackoverflow.com/questions/26984

  •  09-06-2019
  •  | 
  •  

Вопрос

Я был в обеих ситуациях:

  • Создание слишком большого количества пользовательских исключений
  • Использование слишком большого общего класса исключений

В обоих случаях проект стартовал нормально, но вскоре стал накладным для обслуживания (и рефакторинга).

Итак, какова наилучшая практика в отношении создания ваших собственных классов исключений?

Это было полезно?

Решение

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

  • Не пишите собственные исключения (есть много полезных исключений, которые уже являются частью Java API)

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

Другие советы

Не делайте того, что делали разработчики из моей компании.Кто-то создал исключение InvalidArguementException, которое работает параллельно java.lang.Исключение IllegalArgumentException, и теперь мы используем его (буквально) в сотнях классов.Оба указывают на то, что методу был передан недопустимый или неподходящий аргумент.Поговорим о пустой трате времени...

Джошуа Блох описывает это в Эффективное Руководство по языку программирования Java [моя библия первой помощи по передовым практикам] Глава 8.Исключения Пункт 42 повестки дня:Отдавайте предпочтение использованию стандартных исключений.Вот немного из того, что он говорит,

Повторное использование ранее существовавших исключений имеет несколько преимуществ.Главным из них является то, что он упрощает изучение и использование вашего API, потому что это соответствует установленным соглашениям, с которыми программисты уже знакомы [мой акцент, а не Блоха].Во-вторых, программы, использующие ваш API, легче читать, потому что они не загромождены незнакомыми исключениями.Наконец, меньшее количество классов исключений означает меньший объем памяти и меньше времени, затрачиваемого на загрузку классов.

Наиболее часто используемым исключением является IllegalArgumentException.Обычно это исключение, которое возникает, когда вызывающий объект передает аргумент, значение которого не соответствует действительности.Например, это было бы исключением, которое вызывается, если вызывающий объект передал отрицательное число в параметре, представляющем количество раз, которое должно было быть повторено какое-либо действие.

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

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

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

try {
     doIt();
} catch (ExceptionType1 ex1) {
     // do something useful
} catch (ExceptionType2 ex2) {
     // do the exact same useful thing that was done in the block above
}

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

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

Это мое основное правило.

По сути, каждая работа заслуживает отдельного исключения.Когда вы перехватываете исключения, вы не различаете разные экземпляры, как обычно поступаете с объектами, поэтому вам нужны разные подтипы.Использование слишком большого количества пользовательских исключений - это случай, который, как я вижу, вряд ли встречается.

Одним из советов было бы создавать исключения по мере необходимости, и если становится очевидным, что один тип исключения является дубликатом другого, реорганизуйте код, объединив их.Конечно, это помогает, если с самого начала подумать о структурировании исключений.Но, как правило, используйте пользовательские исключения для всех случаев, которые не соответствуют 1: 1 существующим исключениям, зависящим от конкретной ситуации.

С другой стороны, NullPointerExceptionы и IndexOutofBoundsExceptionна самом деле s часто может быть уместным.Однако не перехватывайте их (за исключением регистрации), поскольку они являются ошибкой программирования, которая означает, что после их запуска программа находится в неопределенном состоянии.

Мое собственное эмпирическое правило:

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

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

При создании вашего собственного исключения:

  • Все исключения должны быть дочерними элементами Класс, который можно выбрасывать

  • Если вы хотите написать проверяемое исключение, которое автоматически применяется с помощью правила Handle или Declare, вам необходимо расширить Класс исключений

  • Если вы хотите написать выполнение во время выполнения, вам нужно расширить класс исключений во время выполнения.

Не ешьте исключения, выбрасывайте их https://stackoverflow.com/a/921583/1097600

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

IllegalStateException
UnsupportedOperationException
IllegalArgumentException
NoSuchElementException
NullPointerException

Генерирует непроверенные исключения.

Пример

public void validate(MyObject myObjectInstance) {
    if (!myObjectList.contains(myObjectInstance))
        throw new NoSuchElementException("object not present in list");
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top