Я определяю новый интерфейс API... по общему признанию, не то, что я делаю так часто. Я хотел бы определить методы интерфейса, чтобы выбросить исключение, чтобы обеспечить некоторую гибкость для разработчиков. Затем они могут выбрать бросить исключение, бросить более конкретный подкласс Exception или вообще ничего не бросать. Я несколько раз читал, что, хотя это хорошо, чтобы позволить реализовать классы этой гибкостью, также плохо определить метод интерфейса с "throws Exception". Вместо этого он рекомендовал подкласс Exception (например, MyException) и бросить подкласс. Объяснений для этой практики не было подробно, так что может кто-то подробно остановиться на этой лучшей практике? Спасибо.
Интерфейс Java выбрасывает исключительную практику
Ответ 1
Я могу оценить попытку предоставить разработчикам некоторую гибкость, но исключение является частью API,, поэтому вам следует подумать над тем, что (проверено) исключение (и) имеет смысл.
Говоря throws Exception
, вы не помогаете клиентам интерфейса понять, какие отказы, как ожидается, дадут им возможность реагировать на них соответствующим образом. Вы можете счесть, что принимаете параметр метода Object
, чтобы разработчики могли решить, какие аргументы они могут принять. Это полезно для разработчика, но для кошмаров для интерфейса интерфейса.
Ответ 2
Лучше иметь представление о том, какие исключения вам нужно бросить позже. Там так называемый принцип подписи Лискова, который рекомендует не бросать исключения в подклассы, которые не будут выброшены суперклассом.
Принцип подстановки Лискова ака. дизайн по контракту: http://en.wikipedia.org/wiki/Liskov_substitution_principle
Если вы сомневаетесь в том, что нужно исключить Exception, используйте "throws Exception" (даже если оно uncool). Просто не допускайте неожиданного поведения, реализуя классы, когда они генерируют исключения, если они не были запланированы вами.
В худшем случае будет программист, который отчаянно бросает исключения во время выполнения из-за отсутствия объявлений-бросков.
Ответ 3
Я предпочитаю бросать стандартный подкласс Java RuntimeException
. Это дает гибкость, позволяющую исключать распространение или попадание без ссылки на ваш API.
Есть много подклассов, которые можно выбрать из http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html
Часто я использую IllegalStateException
или IllegalArgumentException
Ответ 4
Подумайте о проверенных исключениях как необязательных возвращаемых значениях. API, методы которого возвращают Object
, по понятным причинам редко, и тот же принцип должен применяться для проверенных исключений.
Ответ 5
Причина того, что метод интерфейса, объявляющий бросить базовый класс Exception
, является плохой практикой, состоит в том, что на самом деле он заставил бы экземпляр этого самого базового класса выполнить юридическую реализацию интерфейса, что является тем, что вы четко хочу избежать.
Вот почему вы должны использовать только специализированные/настраиваемые типы исключений в ваших подписях.
Я бы не стал говорить, что интерфейс не должен объявлять бросание любого Исключения заранее, как кто-то сказал в своем ответе ранее, потому что интерфейс фактически не является свободным плавающим.
Вы, как объявляющий интерфейс, вызываете или используете методы определенным образом, и вы делаете утверждения о том, как методы будут использоваться вашей стороной кода.
На самом деле это контракт, который вы создаете. И исключения являются частью этого контракта. Фактически тот, который использует интерфейс (а не тот, который его реализует), будет выполняться с помощью своего рабочего пути до того, как реализация может существовать.
Ответ 6
в общем случае бросание исключения означает один из двух вариантов:
- попросив звонящего принять действие на основании того, что произошло, обычно надеясь, что у него будет более широкое понимание ситуации, чтобы принять решение.
- Сообщать вызывающему, что действие не выполнено.
фокусировка на первом типе, бросающем определенные исключения, является хорошей идеей, а вызываемая может делать:
try {
} catch (ServerIsBusyException ex) {
// wait 10 sec and continue / try another server
} catch (BadUserNameException ex2) {
// try another name
} ....
Второй тип обычно является RuntimeException s, что означает непредвиденную ситуацию.
см. хорошее объяснение в этом ответе