Java, исключения для классов и стандартные исключения

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

Сначала мне показалось, что я определяю исключения, относящиеся к каждому классу, однако большинство из этих исключений - это просто расширения существующих исключений времени выполнения (например, FooNegativeIntArgumentException extends IllegalArgumentException, FooNullBarException extends NullPointerException) с определенными сообщениями.

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

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

Ответы

Ответ 1

Здесь мой подход к тому, почему мы имеем разные типы исключений и когда создаем настраиваемые типы исключений (обратите внимание: в качестве примеров используются типы .NET но те же самые принципы применимы к Java и любому другому языку, который использует структурированную обработку ошибок). Это, вероятно, слишком долго, чтобы публиковать здесь полный ответ, поэтому я просто опубликую два ключевых отрывка.

  • Когда бросать разные типы исключений? Бросьте другой тип исключения для каждого симптома, который может быть программно обработан по-разному.

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

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

Ответ 2

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

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

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

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

Ответ 3

Из Эффективная Java

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

Упрощает изучение и использование вашего API, поскольку он соответствует установленным соглашениям, с которыми программисты уже знакомы

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

Ответ 4

Возможно ли, что вызывающему нужно было бы уловить FooNegativeIntArgumentException, а не IllegalArgumentException?

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

Ответ 5

Компромисс? Много работы, много кода для поддержания и времени - это деньги. Я бы предложил: определять новые исключения только в том случае, если они вам нужны для фильтрации журналов, обработки мелкозернистых исключений или отладки (установите контрольную точку для специального типа исключения).

Ответ 6

Я бы использовал явно определенные исключения, чтобы дать клиенту больше контроля. Если клиент хочет, они могут поймать IllegalArgumentException, как в вашем примере выше. Если им нужно больше контроля, они могут поймать отдельные типы исключений. Рассмотрим, например, метод, который может генерировать два подкласса IllegalArgumentException. Если вы не являетесь подклассом, вам нужно выполнить синтаксический анализ строки или какую-либо другую бессмысленность, чтобы определить фактическую причину возникшего исключения. Определяемые пользователем типы решают эту проблему.