Twierdzenia Javy

Zastanawiam się, dlaczego słowo kluczowe assert jest tak mało używane w Javie? Prawie nigdy nie widziałem ich używanych, ale myślę, że to świetny pomysł. Zdecydowanie wolę zwięzłość:

assert param != null : "Param cannot be null";

Do słownictwa:

if (param == null) {
    throw new IllegalArgumentException("Param cannot be null");
}

Moje podejrzenie jest takie, że są nieużywane, ponieważ

  • przybyli stosunkowo późno (Java 1.4), do tego czasu Wiele osób już ustaliło swój styl/nawyk programowania w Javie {11]}
  • są domyślnie wyłączone podczas wykonywania, dlaczego OH Dlaczego??
Author: Nils von Barth, 2008-11-18

10 answers

twierdzenia są, w teorii, do testowania niezmienników, założenia, że musi być prawdziwe, aby Kod został poprawnie wypełniony.

Pokazany przykład to testowanie poprawnych danych wejściowych, które nie jest typowym zastosowaniem dla twierdzenia, ponieważ zazwyczaj jest dostarczane przez użytkownika.

Twierdzenia nie są zwykle używane w kodzie produkcyjnym, ponieważ istnieje narzut i zakłada się, że sytuacje, w których niezmienniki zawodzą, zostały wyłapane jako błędy kodowania podczas rozwój i testowanie.

Twój punkt widzenia na to, że przychodzą "późno" do Javy, jest również powodem, dla którego nie są szerzej postrzegane.

Ponadto, struktury testowania jednostkowego pozwalają na pewne potrzeby twierdzeń programowych, aby były zewnętrzne wobec testowanego kodu.

 62
Author: Ken Gentle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-06 17:23:48

To nadużycie twierdzeń, aby używać ich do testowania danych użytkownika. Rzucanie IllegalArgumentException Na nieprawidłowe dane wejściowe jest bardziej poprawne, ponieważ pozwala wywołującej metodę wychwycić wyjątek, wyświetlić błąd i zrobić to, co trzeba (ponownie poprosić o wejście, zamknąć, cokolwiek).

Jeśli ta metoda jest prywatną metodą wewnątrz jednej z Twoich klas, twierdzenie jest w porządku, ponieważ starasz się upewnić, że nie przypadkowo przekazujesz jej argumentu null. Testujesz z twierdzeniami na, a kiedy masz przetestowałem wszystkie ścieżki i nie uruchomiłem twierdzenia, możesz je wyłączyć, aby nie marnować na nie zasobów. Są również przydatne jako komentarze. assert na początku metody jest dobrą dokumentacją dla opiekunów, że powinni przestrzegać pewnych warunków wstępnych, a assert na końcu z dokumentem postcondition dokumentuje, co metoda powinna robić. Mogą być równie przydatne jak komentarze; moreso, bo z twierdzeniami na, faktycznie testują to, co dokument.

Asercje służą do testowania/debugowania, a nie sprawdzania błędów, dlatego są domyślnie wyłączone: aby zniechęcić ludzi do używania asercji do walidacji danych wejściowych użytkownika.

 56
Author: Adam Jaskiewicz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-18 15:03:12

From Programowanie z twierdzeniami

Domyślnie, asercje są wyłączone w czasie wykonywania. Dwa przełączniki wiersza poleceń umożliwiają selektywne Włączanie lub wyłączanie twierdzeń.

Oznacza to, że jeśli nie masz pełnej kontroli nad środowiskiem run-time, nie możesz zagwarantować, że kod asercji zostanie nawet wywołany. Twierdzenia mają być używane w środowisku testowym, a nie w kodzie produkcyjnym. Nie można zastąpić obsługi wyjątków asercjami ponieważ jeśli użytkownik uruchomi Twoją aplikację z wyłączonymi asercjami (default ), cały kod obsługi błędów znika.

 19
Author: Bill the Lizard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-18 15:01:32

W "efektywnej Javie" Joshua Bloch zasugerował (w temacie "Check parameters for validity"), że (coś w rodzaju prostej reguły do przyjęcia), dla metod publicznych, powinniśmy zweryfikować argumenty i wyrzucić niezbędny wyjątek, jeśli okaże się nieważny, a dla metod niepublicznych (które nie są narażone i Ty jako użytkownik powinieneś zapewnić ich ważność), możemy użyć assertion zamiast.

Yc

 18
Author: yclian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-18 18:21:25

@Don, jesteś sfrustrowany, że twierdzenia są domyślnie wyłączone. Byłem również, i tak napisał ten mały plugin javac, który je inlines (ie emituje bajt kod dla if (!expr) throw Ex zamiast tego głupiego bajt kodu.

Jeśli wpiszesz fa.jar w Twojej classpath podczas kompilacji kodu Javy, wykona swoją magię, a następnie powie

Note: %n assertions inlined.

@ see http://smallwiki.unibe.ch/adriankuhn/javacompiler/forceassertions i ewentualnie na GitHubie https://github.com/akuhn/javac

 9
Author: akuhn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-12 08:12:02

Nie jestem pewien, po co mielibyście pisać twierdzenia, a następnie zastępować je standardową instrukcją if then condition, dlaczego w ogóle nie zapisywać Warunków jako ifs?

Asserts są przeznaczone tylko do testowania i mają dwa skutki uboczne: większe pliki binarne i obniżoną wydajność po włączeniu (dlatego możesz je wyłączyć!)

Asserts nie powinny być używane do walidacji warunków, ponieważ oznacza to, że zachowanie aplikacji jest INNE w czasie uruchamiania, gdy asserts są włączone/wyłączone - co jest koszmarem!

 2
Author: Nimbus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-09 13:40:50

Twierdzenia są bardzo ograniczone: możesz testować tylko Warunki logiczne i za każdym razem musisz napisać kod, aby uzyskać użyteczny komunikat o błędzie. Porównaj to z metodą assertEquals() JUnit, która pozwala wygenerować użyteczny komunikat o błędzie z wejść, a nawet pokazać dwa wejścia obok siebie w IDE w runnerze JUnit.

Ponadto, nie możesz szukać twierdzeń w żadnym IDE, które do tej pory widziałem, ale każde IDE może wyszukiwać wywołania metod.

 1
Author: Aaron Digulla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-18 14:57:00

Twierdzenia są użyteczne, ponieważ:

  • wcześnie wyłapuj błędy programowania
  • kod dokumentu z wykorzystaniem kodu

Pomyśl o nich jako o samowalidacji kodu. Jeśli się nie powiedzie, powinno to oznaczać, że twój program jest zepsuty i musi się zatrzymać. Zawsze włączaj je podczas testów jednostkowych !

W pragmatyczny programista zalecają nawet, aby pozwolić im działać w produkcji.

Leave Assertions On

Użyj twierdzeń, aby zapobiec Niemożliwe.

Zauważ, że asercje rzucają AssertionError, jeśli się nie powiedzie, więc nie są przechwytywane przez wyjątek catch.

 1
Author: Christophe Roussy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-29 08:12:43

W rzeczywistości przybyli w Javie 1.4

Myślę, że głównym problemem jest to, że gdy kodujesz w środowisku, w którym nie zarządzasz bezpośrednio opcjami jvm przez siebie, jak w serwerach eclipse lub J2EE (w obu przypadkach można zmienić opcje jvm, ale trzeba głęboko szukać, aby znaleźć, gdzie można to zrobić), jest łatwiej (mam na myśli, że wymaga mniej wysiłku) używać if I wyjątków (lub gorzej nie używać niczego).

 0
Author: Denis R.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-18 14:44:23

Jak stwierdzili inni: twierdzenia nie są odpowiednie do walidacji danych wejściowych użytkownika.

Jeśli interesuje Cię werbalność, polecam zajrzeć do biblioteki, którą napisałem: https://bitbucket.org/cowwoc/requirements/. pozwoli Ci to wyrazić te kontrole za pomocą bardzo małego kodu, a nawet wygeneruje komunikat o błędzie w Twoim imieniu:

requireThat("name", value).isNotNull();

I jeśli nalegasz na używanie twierdzeń, możesz też to zrobić:

assertThat("name", value).isNotNull();

Wynik będzie wyglądał następująco:

java.lang.NullPointerException: name may not be null
 0
Author: Gili,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-30 21:40:34