Чи повинні методи, які кидають RuntimeException, вказувати це в підписі методу?


86

Наприклад, багато методів у фреймворках / JDK можуть кидати

java.lang.SecurityException 

але це не зазначено в підписі методу (оскільки це практика, яка зазвичай зарезервована для перевірених винятків). Я хочу заперечити, що оголошення RuntimeExceptions у методі sigs має багато переваг (подібних до перевірки статичного типу, наприклад). Я п'яний чи інакше?

Відповіді:


70

Я б не оголошував у підписі неперевірений виняток, оскільки це вводить в оману користувача цього API. Більше не очевидно, чи потрібно чітко обробляти виняток.

Оголошення цього в javadoc - кращий підхід, оскільки він дозволяє комусь з цим впоратися, якщо вони вважають це необхідним, але знаючи, що можуть ігнорувати його, якщо хочуть. Це робить чітким розділення між перевіреним та неперевіреним.


4
Компілятор Java не змушує вас обробляти заявлені RuntimeExceptions. Таким чином, ви можете оголосити їх як "підказку" для розробників. Можна обговорювати, якщо JavaDoc є кращим місцем для цього. Важливим є пункт про перевірені та неперевірені винятки. Перевірені та не позначені винятки - це те, що насправді означає Java із винятками (Compiletime-) (позначено) та RuntimeExceptions (не позначено).
Guardian667

5
Навесні декларування неперевірених винятків у підписі методів стало звичною практикою.
nascar

38

З підручника з Oracle Java :

"Якщо так добре задокументувати API методу, включаючи винятки, які він може створити, чому б не вказати також винятки під час виконання?" Винятки під час виконання представляють проблеми, які є результатом проблеми програмування, і тому не можна розумно очікувати, що код клієнта API відновлюється від них або обробляє їх будь-яким чином. До таких проблем належать арифметичні винятки, такі як ділення на нуль; винятки покажчиків, такі як спроба отримати доступ до об'єкта через нульове посилання; та індексування винятків, таких як спроба отримати доступ до елемента масиву за допомогою занадто великого або замалого індексу.

Винятки під час виконання можуть траплятися в будь-якому місці програми, а в типовому варіанті їх може бути дуже багато. Додавання винятків часу виконання в кожному оголошенні методу зменшить ясність програми.


Таким чином, компілятор не вимагає, щоб ви ловили або вказували винятки під час виконання (хоча ви можете).
nascar

18

Погляньте на javadoc для колекції # 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 для методу. Заявлення про це в підписі робить ще більш очевидним, що може статися, коли щось піде не так. Це моя головна причина для пропозиції надати цю інформацію.

FYI: з плином часу (тепер у 2017 році) я зараз нахиляюсь набагато більше до документування їх лише у javadoc та, наскільки це можливо, уникаю перевірених винятків.


3

На мій погляд, неперевірені винятки ніколи не повинні оголошуватися в підписі методу, оскільки це суперечить їх природі.

Якщо, однак, метод, швидше за все, видасть деякі неперевірені винятки, зазначивши ймовірні обставини в @throws в Javadoc, може бути корисним для інших, хто використовує метод, щоб зрозуміти, що може піти не так. Це корисно лише для винятків, з якими, мабуть, зможуть обробляти абоненти (наприклад, NPE через поганий вхід тощо)


3

Якщо ви пишете api для використання іншими, тоді є достатньо підстав для явного документування вашого наміру в api, і немає недоліків у оголошенні RuntimeExceptions у підписі методу.


1

Це пов’язано з дискусією щодо перевірених винятків . Більшість погодиться, що винятки не повинні оголошуватися в підписах методів.

Існує також дискусія щодо того, як слід використовувати винятки під час виконання. Я погоджуюсь з одним плакатом, що винятки під час виконання повинні позначати помилку програмування або фатальний стан. Отже, немає великої заслуги в тому, щоб оголосити їх у підписі. Кожен метод може потенційно через один.


Куди тоді входить виняток синтаксичного аналізу або якийсь інший виняток типу перевірки даних. Ви маєте на увазі, що ви не повинні використовувати перевірені винятки, але потім обмежуєте те, для чого призначені неперевірені винятки.
Робін

1
Я хочу сказати, що розробника не слід змушувати ловити перевірені винятки. Тому немає необхідності оголошувати їх у підписі методу. У Java ви можете перетворити їх у винятках під час виконання, як це робить Spring. Я також кажу, що винятки під час виконання повинні застосовуватися лише в ситуаціях, що не підлягають відновленню.
kgiannakakis
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.