Рубрики
Без рубрики

Эффективная Java: Генерирует Исключения, Соответствующие Абстракции

Погружение в главу 73 “Эффективная Java”. Помеченный как java, эффективный, исключения, архитектура.

Большая часть Effective Java фокусируется на создании чистого, понятного API и на том, как это является основой отличной библиотеки. Частью API класса являются любые исключения, которые он может создавать в стеке, как отмеченные (где они становятся частью подписи), так и непроверенные. Как авторы кода, мы несем ответственность за то, чтобы убедиться, что в этом API нет никаких сюрпризов или чего-то шокирующего. Один из способов, которым это может произойти, заключается в выявлении исключения, которое не имеет смысла для класса, который мы пишем.

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

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

public E get(int index) {
  ListIterator = listIterator(index);
  try {
    return i.next();
  } catch (NoSuchElementException e) {
    throw new IndexOutOfBoundsException("Index: " + index);
  }
}

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

Особая форма преобразования исключений – это когда вы оборачиваете исключение более низкого уровня в исключение более высокого уровня, но также передаете исключение более низкого уровня в исключение более высокого уровня как причину . Многие методы предоставляют это поле причины, и оно передается в класс Throwable. Если конкретный метод не раскрывает причину в своей конструкции, вы даже можете вызвать Выбрасываемый ‘s initCause при исключении. Выбрасываемый обеспечивает getCause метод, который затем может быть использован выше в стеке для извлечения основной проблемы. Что еще более важно, эта причина выявляется с помощью трассировки стека, что может значительно помочь в отладке проблем. Это косвенно раскрывает сведения более низкого уровня вызывающему методу. Он, однако, делает это не очень напрямую, поэтому он не заставляет вызывающую сторону обрабатывать исключение низкого уровня, но вместо этого они все равно могут обрабатывать исключение высокого уровня и не беспокоиться о деталях реализации низкого уровня.

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

Всегда помните, что любые создаваемые исключения являются частью вашего API. Таким образом, вы должны принять во внимание, какое исключение вы создаете и отправляете своим абонентам. Убедитесь, что эти исключения соответствуют абстракции, над которой работает ваш код. Если у вас действительно возникают исключения более низкого уровня, используйте шаблон exception translation для преобразования этого исключения в тип исключения более высокого уровня, соответствующий вашей абстракции. Кроме того, рассмотрите возможность использования поля cause в таких перехваченных и повторно созданных исключениях. Делая это, вы можете в конечном итоге упростить чтение, обслуживание и изменение кода.

Оригинал: “https://dev.to/kylec32/effective-java-throw-exceptions-appropriate-to-the-abstraction-1d4e”