Должны ли методы, генерирующие исключение RuntimeException, указывать это в сигнатуре метода?

86

Например, многие методы в frameworks / JDK могут вызывать

java.lang.SecurityException 

но это не указано в сигнатуре метода (поскольку такая практика обычно применяется для проверенных исключений). Я хочу утверждать, что объявление RuntimeExceptions в методах sigs имеет много преимуществ (например, сродни проверке статического типа). Я пьян или нет?

Жак Рене Мезрин
источник

Ответы:

70

Я бы не объявлял непроверенное исключение в подписи, так как это вводит в заблуждение пользователя этого API. Больше не очевидно, нужно ли обрабатывать исключение явно.

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

Робин
источник
4
Компилятор java не заставляет вас обрабатывать объявленные исключения RuntimeExceptions. Таким образом, вы можете объявить их в качестве «подсказки» для разработчиков. Это можно обсудить, если JavaDoc подходит для этого лучше. Важно отметить отмеченные и непроверенные исключения. Отмеченные и непроверенные Исключения - это то, что на самом деле означает Java с (Compiletime-) Исключениями (отмечен) и RuntimeExceptions (не отмечен).
Guardian667
5
В Spring объявление неотмеченных исключений в сигнатуре метода стало обычной практикой.
nascar
38

Из учебника Oracle Java :

«Если так хорошо документировать API метода, включая исключения, которые он может генерировать, почему бы не указать и исключения времени выполнения?» Исключения времени выполнения представляют собой проблемы, которые являются результатом проблемы программирования, и поэтому нельзя разумно ожидать, что клиентский код API восстановит их или обработает их каким-либо образом. К таким проблемам относятся арифметические исключения, такие как деление на ноль; исключения указателя, такие как попытка доступа к объекту через пустую ссылку; и исключения индексации, такие как попытка доступа к элементу массива через слишком большой или слишком маленький индекс.

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

Дирадж Вепакомма
источник
Таким образом, компилятор не требует, чтобы вы перехватывали или указывали исключения времени выполнения (хотя вы можете).
nascar
18

Взгляните на javadoc для Collection # add

Упоминается целый ряд непроверенных исключений:

Throws:
UnsupportedOperationException - add is not supported by this collection.
ClassCastException - class of the specified element prevents it from being added to this collection.
NullPointerException - if the specified element is null and this collection does not support null elements.
IllegalArgumentException - some aspect of this element prevents it from being added to this collection.

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

Сэм Барнум
источник
6
Это неверный ответ. Вы говорите о операторах Javadoc, а вопрос о throwsсигнатуре метода. Это не одно и то же. Да, вы обязательно должны документировать все исключения, создаваемые вашим API, но вопрос не в этом.
Гили
8

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

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

Патрик Корнелиссен
источник
3

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

Однако, если метод может вызвать некоторые непроверенные исключения, отметка вероятных обстоятельств в @throws в Javadoc может быть полезна для других, вызывающих метод, чтобы понять, что может пойти не так. Это полезно только для исключений, которые вызывающие, вероятно, смогут обработать (например, NPE из-за неправильного ввода и т. Д.)

Крис
источник
3

Если вы пишете api для использования другими, то есть достаточные основания для явного документирования ваших намерений в api, и нет недостатка в объявлении RuntimeExceptions в сигнатуре метода.

alphazero
источник
1

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

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

Кгианнакакис
источник
Где тогда подходит исключение синтаксического анализа или какое-либо другое исключение типа проверки данных. Вы подразумеваете, что вы не должны использовать проверенные исключения, а затем ограничиваете, для чего предназначены непроверенные исключения.
Робин
1
Я говорю о том, что разработчика не следует заставлять ловить проверенные исключения. Таким образом, нет необходимости объявлять их в сигнатуре метода. В Java вы можете преобразовать их в исключения времени выполнения, как это делает Spring. Я также говорю, что исключения времени выполнения должны создаваться только в невосстановимых ситуациях.
kgiannakakis