Pochodzę z tła .NET, a teraz pracuję w Javie.Programowanie defensywne: Wytyczne w Javie
Obecnie mam duże problemy z zaprojektowaniem API w defensywny sposób przeciwko błędnym wejściom. Powiedzmy, że mam następujący kod (na tyle blisko):
public void setTokens(Node node, int newTokens) {
tokens.put(node, newTokens);
}
Jednak ten kod może nie z dwóch powodów:
- Użytkownik przechodzi węzeł
null
. - Użytkownik przekazuje nieprawidłowy węzeł, tj. Jeden nie jest zawarty na wykresie.
W .NET, chciałbym rzucić ArgumentNullException
(zamiast NullReferenceException
!) Lub ArgumentException
odpowiednio, przekazując nazwę argumentu naruszającego (node
) jako string
argument.
Java wydaje się nie mieć równoważnych wyjątków. Zdaję sobie sprawę, że mogę być bardziej konkretny i po prostu wyrzucić wszystko, co jest najbliższe opisania sytuacji, lub nawet napisać własną klasę wyjątków dla konkretnej sytuacji.
Czy to najlepsza praktyka? Czy istnieją klasy uniwersalne podobne do ArgumentException
w .NET?
Czy w takim przypadku warto sprawdzić pod kątem null
? Kod i tak się nie powiedzie, a ślad stosu wyjątku będzie zawierał powyższe wywołanie metody. Sprawdzenie przed null
wydaje się zbyteczne i nadmierne. To prawda, że ślad stosu będzie nieco czystszy (ponieważ jego celem jest powyższa metoda, a nie wewnętrzna kontrola implementacji środowiska JRE). Ale to musi być skompensowane kosztem dodatkowego oświadczenia if
, które ponadto powinno być nigdy nie występuje - przecież przekazanie null
do powyższej metody nie jest oczekiwaną sytuacją, jest to raczej głupi błąd. Oczekiwanie, że jest to wręcz paranoidalne - i zakończy się niepowodzeniem z tym samym wyjątkiem, nawet jeśli nie sprawdzę.
[Jak podkreślono w komentarzach, HashMap.put
faktycznie zezwala na wartości null
dla klucza. Więc sprawdzić przed null
nie byłoby to zbędne tutaj]
Wywołanie "setTokens (null, 0)" spowoduje tylko "NullPointerException", jeśli używasz 'HashTable' lub' ConcurrentHashMap', ponieważ nie pozwalają one na klucze 'null'. "HashMap" z drugiej strony cieszy się, że ma puste klucze. – pjp
@pjp: Dzięki za korektę - spodziewałem się, że to się nie powiedzie, ponieważ 'HashMap' musi stworzyć mieszankę swojego argumentu. Jest jeszcze jeden powód do wyraźnego sprawdzenia. –