Czy metody, które generują wyjątek RuntimeException, powinny wskazywać to w sygnaturze metody?

86

Na przykład wiele metod w frameworkach / JDK może generować

java.lang.SecurityException 

ale nie jest to wskazane w sygnaturze metody (ponieważ jest to praktyka zwykle zarezerwowana dla sprawdzonych wyjątków). Chcę argumentować, że deklarowanie wyjątków RuntimeExceptions w sigs metod ma wiele zalet (na przykład podobne do statycznego sprawdzania typu). Jestem pijany czy nie?

Jacques René Mesrine
źródło

Odpowiedzi:

70

Nie deklarowałbym niezaznaczonego wyjątku w podpisie, ponieważ wprowadza on w błąd użytkownika tego interfejsu API. Nie jest już oczywiste, czy wyjątek musi być jawnie obsługiwany.

Zadeklarowanie go w javadoc jest lepszym podejściem, ponieważ pozwala komuś zająć się tym, jeśli uważa, że ​​jest to konieczne, ale wiedząc, że może to zignorować, jeśli chce. To sprawia, że ​​rozdział między zaznaczonymi i niezaznaczonymi jest wyraźny.

Rudzik
źródło
4
Kompilator java nie zmusza cię do obsługi zadeklarowanych wyjątków RuntimeExceptions. Możesz więc je zadeklarować jako „wskazówkę” dla programistów. Można dyskutować, czy JavaDoc jest lepszym miejscem do tego. Ważna jest kwestia zaznaczonych i niezaznaczonych wyjątków. Zaznaczone i niezaznaczone Wyjątki to to, co Java naprawdę oznacza z (Compiletime-) Exceptions (zaznaczone) i RuntimeExceptions (niezaznaczone).
Guardian667
5
Wiosną deklarowanie niesprawdzonych wyjątków w podpisie metody stało się powszechną praktyką.
nascar,
38

Z samouczka Oracle Java :

„Jeśli tak dobrze jest udokumentować API metody, w tym wyjątki, które może generować, dlaczego nie określić również wyjątków czasu wykonywania?” Wyjątki środowiska wykonawczego reprezentują problemy, które są wynikiem problemu programistycznego i jako takie nie można rozsądnie oczekiwać, że kod klienta API po nich odzyska lub poradzi sobie z nimi w jakikolwiek sposób. Takie problemy obejmują wyjątki arytmetyczne, takie jak dzielenie przez zero; wyjątki dotyczące wskaźnika, takie jak próba uzyskania dostępu do obiektu przez odwołanie o wartości null; i wyjątki indeksowania, takie jak próba uzyskania dostępu do elementu tablicy za pośrednictwem indeksu, który jest za duży lub za mały.

Wyjątki w czasie wykonywania mogą wystąpić w dowolnym miejscu programu, aw typowym programie mogą być bardzo liczne. Konieczność dodania wyjątków czasu wykonywania w każdej deklaracji metody zmniejszyłaby przejrzystość programu.

Dheeraj Vepakomma
źródło
W związku z tym kompilator nie wymaga przechwytywania ani określania wyjątków czasu wykonywania (chociaż można to zrobić).
nascar,
18

Spójrz na javadoc dla Collection # add

Wspomniano o całej masie niezaznaczonych wyjątków:

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.

Jeśli masz cierpliwość, polecam dokładnie udokumentować w ten sposób możliwe wyjątki generowane przez twoje metody. W pewnym sensie jest to jeszcze ważniejsze, aby zrobić to dla niezaznaczonych wyjątków, ponieważ sprawdzone wyjątki są w pewnym stopniu samodokumentujące (kompilator wymusza na kodzie wywołującym ich potwierdzenie).

Sam Barnum
źródło
6
Ta odpowiedź jest błędna. Mówisz o instrukcjach Javadoc, a pytanie o throwsw sygnaturze metody. To nie to samo. Tak, absolutnie powinieneś udokumentować wszystkie wyjątki generowane przez Twój interfejs API, ale nie o to chodzi.
Gili
8

Z mojego punktu widzenia lepiej jest zadeklarować wyjątki czasu wykonywania przynajmniej w javadoc dla metody. Zadeklarowanie tego w podpisie czyni jeszcze bardziej oczywistym, co może się stać, gdy coś pójdzie nie tak. To jest mój główny powód, dla którego sugeruję podanie tych informacji.

Do Twojej wiadomości: w miarę upływu czasu (obecnie w 2017 r.) Skłaniam się teraz znacznie bardziej do dokumentowania ich wyłącznie w javadoc i unikania sprawdzonych wyjątków w miarę możliwości.

Patrick Cornelissen
źródło
3

Moim zdaniem niesprawdzone wyjątki nigdy nie powinny być deklarowane w sygnaturze metody, ponieważ jest to sprzeczne z ich naturą.

Jeśli jednak metoda prawdopodobnie wyrzuci kilka niezaznaczonych wyjątków, zauważenie prawdopodobnych okoliczności w @throws w Javadoc może być pomocne dla innych wywołujących metodę w zrozumieniu, co może pójść nie tak. Jest to przydatne tylko w przypadku wyjątków, które wywołujący prawdopodobnie będą w stanie obsłużyć (takich jak NPE z powodu złych danych wejściowych itp.)

Kris
źródło
3

Jeśli piszesz interfejs API do użytku przez innych, istnieje wystarczający powód, aby wyraźnie udokumentować swój zamiar w interfejsie API i nie ma żadnych wad deklarowania wyjątków RuntimeExceptions w sygnaturze metody.

alphazero
źródło
1

Ma to związek z dyskusją dotyczącą zaznaczonych wyjątków . Większość zgodziłaby się, że wyjątki nie powinny być deklarowane w sygnaturach metod.

Omówiono również sposób korzystania z wyjątków środowiska uruchomieniowego . Zgadzam się z jednym plakatem, że wyjątki środowiska wykonawczego powinny oznaczać błąd programowania lub stan krytyczny. Więc nie ma wiele zasług w deklarowaniu ich w podpisie. Każda metoda może potencjalnie przez jedną.

kgiannakakis
źródło
Gdzie wtedy pasuje wyjątek analizy lub inny wyjątek typu walidacji danych. Sugerujesz, że nie powinieneś używać zaznaczonych wyjątków, ale następnie ograniczasz, do czego mają być używane niezaznaczone wyjątki.
Robin
1
Mówię o tym, że deweloper nie powinien być zmuszany do wyłapywania sprawdzonych wyjątków. Nie ma więc potrzeby ich deklarowania w podpisie metody. W Javie można je przekształcić w wyjątki czasu wykonywania, tak jak robi to Spring. Mówię również, że wyjątki środowiska uruchomieniowego powinny być rzucane tylko w sytuacjach, których nie można odzyskać.
kgiannakakis