Руководство по распространению исключений (на Java) - PullRequest
41 голосов
/ 24 августа 2010

Существуют ли рекомендации по распространению исключений в Java?

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

Есть ли хорошие практики? Есть плохие практики?

Извините, если я неясен, но я просто ищу несколько (общих) советов по стилю программирования относительно исключений.

Ответы [ 2 ]

52 голосов
/ 24 августа 2010

Рекомендации, которые помогли мне в прошлом, включают:

  • Бросать исключения, когда метод не может обработать исключение , и, что более важно, должен обрабатываться вызывающей стороной. Хорошим примером этого является представление в Servlet API - doGet () и doPost () генерируют ServletException или IOException в определенных обстоятельствах, когда запрос не может быть прочитан правильно. Ни один из этих методов не в состоянии обработать исключение, но контейнер является (что приводит к 50-кратной ошибке страницы в большинстве случаев).
  • Обсудить исключение, если метод не может его обработать . Это является следствием вышесказанного, но применимо к методам, которые должны перехватить исключение. Если перехваченное исключение не может быть правильно обработано методом, то предпочтительно всплыть.
  • Брось исключение сразу . Это может показаться расплывчатым, но если встречается сценарий исключения, то рекомендуется генерировать исключение, указывающее исходную точку отказа, вместо того, чтобы пытаться обработать сбой с помощью кодов ошибок, пока точка не будет сочтена подходящей для выброса исключения. , Другими словами, попытайтесь минимизировать смешивание обработки исключений с обработкой ошибок.
  • Либо зарегистрируйте исключение, либо вышлите его, но не делайте и то и другое . Регистрация исключения часто указывает на то, что стек исключений был полностью размотан, что указывает на то, что дальнейшего исключения не произошло. Следовательно, не рекомендуется делать и то и другое одновременно, так как это часто приводит к разочаровывающему опыту отладки.
  • Используйте подклассы java.lang.Exception (проверенные исключения), когда вы, кроме вызывающей стороны, обрабатываете исключение . Это приводит к тому, что компилятор выдает сообщение об ошибке, если вызывающая сторона не обрабатывает исключение. Однако будьте осторожны, это обычно приводит к тому, что разработчики «проглатывают» исключения в коде.
  • Используйте подклассы java.lang.RuntimeException (непроверенные исключения), чтобы сигнализировать об ошибках программирования . Классы исключений, которые здесь рекомендуются, включают IllegalStateException , IllegalArgumentException , UnsupportedOperationException и т. Д. Опять же, следует соблюдать осторожность при использовании классов исключений, таких как NullPointerException (почти всегда плохо практиковаться, чтобы бросить один).
  • Использование иерархий классов исключений для передачи информации об исключениях по различным уровням . Реализуя иерархию, вы можете обобщить поведение обработки исключений в вызывающей стороне. Например, вы можете использовать корневое исключение, такое как DomainException, которое имеет несколько подклассов, таких как InvalidCustomerException, InvalidProductException и т. Д. Здесь предостережение заключается в том, что ваша иерархия исключений может взорваться очень быстро, если вы представляете каждый отдельный исключительный сценарий как отдельное исключение.
  • Избегайте перехвата исключений, с которыми вы не можете справиться . Довольно очевидно, но многие разработчики пытаются поймать java.lang.Exception или java.lang.Throwable. Поскольку все подклассовые исключения могут быть перехвачены, поведение приложения во время выполнения часто может быть расплывчатым при обнаружении «глобальных» классов исключений. В конце концов, никто не хотел бы поймать OutOfMemoryError - как следует обрабатывать такое исключение?
  • Оберните исключения с осторожностью . Повторное создание исключения сбрасывает стек исключений. Если исходная причина не была предоставлена ​​новому объекту исключения, она теряется навсегда. Чтобы сохранить стек исключений, необходимо предоставить исходный объект исключения конструктору нового исключения.
  • Конвертировать отмеченные исключения в непроверенные только при необходимости .При переносе исключения можно обернуть проверенное исключение и выбросить непроверенное.Это полезно в определенных случаях, особенно когда предполагается отменить текущий выполняющийся поток.Однако в других сценариях это может причинить небольшую боль, так как проверки компилятором не выполняются.Поэтому адаптировать проверенное исключение как непроверенное нельзя делать вслепую.
2 голосов
/ 24 августа 2010

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

Плохая практика в отношении исключений - ловить их всех (это не покемон, это java!), Поэтому избегайте catch(Exception e) или хуже catch(Throwable t).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...