Do czego służy słowo kluczowe Java assert i kiedy powinno być używane?

Jakie są prawdziwe przykłady życia , aby zrozumieć kluczową rolę twierdzeń?

17 answers

Assertions (przy pomocy słowa kluczowego assert) zostały dodane w Javie 1.4. Służą one do weryfikacji poprawności niezmiennika w kodzie. Nigdy nie powinny być uruchamiane w kodzie produkcyjnym i wskazują na błąd lub niewłaściwe użycie ścieżki kodu. Mogą być aktywowane w czasie wykonywania za pomocą opcji -ea w Komendzie java, ale nie są domyślnie włączone.

Przykład:

public Foo acquireFoo(int id) {
  Foo result = null;
  if (id > 50) {
    result = fooService.read(id);
  } else {
    result = new Foo(id);
  }
  assert result != null;

  return result;
}
 375
Author: Ophidian,
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
2015-09-02 16:25:18

Załóżmy, że powinieneś napisać program do sterowania elektrownią jądrową. Jest całkiem oczywiste, że nawet najmniejszy błąd może mieć katastrofalne skutki, dlatego Twój kod musi być wolny od błędów(zakładając, że JVM jest wolny od błędów dla dobra argumentu).

Java nie jest językiem weryfikowalnym, co oznacza, że nie można obliczyć, że wynik twojej operacji będzie doskonały. Głównym tego powodem są wskaźniki: mogą wskazywać w dowolnym miejscu lub nigdzie, dlatego nie można ich obliczyć, aby miały taką dokładną wartość, przynajmniej nie w rozsądnym zakresie kodu. Biorąc pod uwagę ten problem, nie ma sposobu, aby udowodnić, że Twój kod jest poprawny w całości. Ale to, co możesz zrobić, to udowodnić, że przynajmniej znajdziesz każdy błąd, gdy to się stanie.

Idea ta opiera się na paradygmacie Design-by-Contract (DbC): najpierw definiujesz (z matematyczną precyzją), co ma robić twoja metoda, a następnie weryfikujesz to, testując ją podczas rzeczywistego egzekucja. Przykład:

// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
  return a + b;
}

Chociaż jest to dość oczywiste, że działa dobrze, większość programistów nie zobaczy ukrytego błędu wewnątrz tego (wskazówka: Ariane V rozbił się z powodu podobnego błędu). Teraz DbC definiuje, że musisz zawsze sprawdzać wejście i wyjście funkcji, aby sprawdzić, czy działa poprawnie. Java może to zrobić poprzez twierdzenia:

// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
    assert (Integer.MAX_VALUE - a >= b) : "Value of " + a + " + " + b + " is too large to add.";
  final int result = a + b;
    assert (result - a == b) : "Sum of " + a + " + " + b + " returned wrong sum " + result;
  return result;
}

Jeśli ta funkcja kiedykolwiek zawiedzie, zauważysz to. Będziesz wiedział, że w Twoim kodzie jest problem, wiesz gdzie to jest i wiesz co spowodowało (podobnie jak wyjątki). A co jeszcze ważniejsze: przestajesz wykonywać poprawnie, gdy uniemożliwia to dalsze działanie kodu z niewłaściwymi wartościami i potencjalnie powoduje uszkodzenie tego, co kontroluje.

Wyjątki Javy są podobną koncepcją, ale nie sprawdzają wszystkiego. Jeśli chcesz jeszcze więcej sprawdzeń (kosztem szybkości wykonania), musisz użyć twierdzeń. W ten sposób będzie nadmuchać kod, ale można w końcu dostarczyć produkt w zaskakująco krótki czas rozwoju (im wcześniej naprawisz błąd, tym niższy koszt). Ponadto: jeśli w Twoim kodzie jest jakiś błąd, to go wykryjesz. Nie ma sposobu, aby błąd prześlizgnął się i spowodował problemy później.

To nadal nie jest gwarancją wolnego od błędów kodu, ale jest do tego znacznie bliżej niż zwykłe programy.

 291
Author: TwoThe,
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
2018-04-14 04:53:14

Assertions to narzędzie fazy rozwojowej do wyłapywania błędów w kodzie. Są zaprojektowane tak, aby można je było łatwo usunąć, więc nie będą istniały w kodzie produkcyjnym. Tak więc twierdzenia nie są częścią "rozwiązania", które dostarczasz klientowi. To wewnętrzne kontrole, aby upewnić się, że twoje założenia są poprawne. Najczęstszym przykładem jest test na null. Wiele metod jest napisanych w ten sposób:

void doSomething(Widget widget) {
  if (widget != null) {
    widget.someMethod(); // ...
    ... // do more stuff with this widget
  }
}

Bardzo często w takiej metodzie widżet nigdy nie powinien być null. Więc jeśli jest null, gdzieś w Twoim kodzie jest błąd, który musisz wyśledzić. Ale powyższy kod nigdy ci tego nie powie. Więc w dobrej intencji, aby napisać "bezpieczny" kod, ukrywasz również błąd. O wiele lepiej napisać taki kod:

/**
 * @param Widget widget Should never be null
 */
void doSomething(Widget widget) {
  assert widget != null;
  widget.someMethod(); // ...
    ... // do more stuff with this widget
}

W ten sposób na pewno złapiesz ten błąd wcześnie. (Warto również określić w umowie, że parametr ten nigdy nie powinien być null.) Pamiętaj, aby włączyć assertions podczas testowania kodu podczas tworzenia. (I przekonywanie twoi koledzy też to robią, często jest to trudne, co uważam za bardzo denerwujące.)

Teraz, niektórzy z twoich kolegów sprzeciwią się temu kodowi, argumentując, że nadal powinieneś umieścić sprawdzanie null, aby zapobiec wyjątkowi w produkcji. W takim przypadku twierdzenie jest nadal użyteczne. Możesz to napisać Tak:

void doSomething(Widget widget) {
  assert widget != null;
  if (widget != null) {
    widget.someMethod(); // ...
    ... // do more stuff with this widget
  }
}

W ten sposób Twoi koledzy będą zadowoleni, że sprawdzanie null jest dostępne dla kodu produkcyjnego, ale podczas tworzenia nie ukrywasz już błędu, gdy widget jest null.

Oto prawdziwy przykład: napisałem kiedyś metodę porównującą dwie dowolne wartości dla równości, gdzie każda wartość może być null:

/**
 * Compare two values using equals(), after checking for null.
 * @param thisValue (may be null)
 * @param otherValue (may be null)
 * @return True if they are both null or if equals() returns true
 */
public static boolean compare(final Object thisValue, final Object otherValue) {
  boolean result;
  if (thisValue == null) {
    result = otherValue == null;
  } else {
    result = thisValue.equals(otherValue);
  }
  return result;
}

Ten kod deleguje pracę metody equals() W przypadku, gdy thisValue nie jest null. Zakłada jednak, że metoda equals() prawidłowo spełnia kontrakt equals() poprzez prawidłowe operowanie parametrem null.

Kolega sprzeciwił się mojemu kodowi, mówiąc mi, że wiele naszych klas ma wadliwe metody, które nie sprawdzają dla null, więc powinienem umieścić to sprawdzenie w tej metodzie. Jest to dyskusyjne, czy jest to mądre, czy powinniśmy wymusić błąd, abyśmy mogli go wykryć i naprawić, ale odroczyłem do mojego kolegi i wstawiłem sprawdzenie null, które zaznaczyłem komentarzem: {]}

public static boolean compare(final Object thisValue, final Object otherValue) {
  boolean result;
  if (thisValue == null) {
    result = otherValue == null;
  } else {
    result = otherValue != null && thisValue.equals(otherValue); // questionable null check
  }
  return result;
}

Dodatkowa kontrola tutaj, other != null, jest konieczna tylko wtedy, gdy metoda equals() nie sprawdza null zgodnie z wymaganiami umowy.

Zamiast angażować się w bezowocną debatę z moim kolegą na temat mądrości pozwalającej buggy kod pozostań w naszej bazie kodów, po prostu umieszczam w kodzie dwa twierdzenia. Te twierdzenia dadzą mi znać, w fazie rozwoju, jeśli jedna z naszych klas nie zaimplementuje equals() poprawnie, więc mogę to naprawić:

public static boolean compare(final Object thisValue, final Object otherValue) {
  boolean result;
  if (thisValue == null) {
    result = otherValue == null;
    assert otherValue == null || otherValue.equals(null) == false;
  } else {
    result = otherValue != null && thisValue.equals(otherValue);
    assert thisValue.equals(null) == false;
  }
  return result;
}
Ważne punkty, o których należy pamiętać, to:]}
  1. Twierdzenia są tylko narzędziami fazy rozwoju.

  2. Celem twierdzenia jest poinformowanie Cię, czy jest błąd, nie tylko w Twoim kodzie, ale w bazie . (The twierdzenia tutaj faktycznie oznaczą błędy w innych klasach.)

  3. Nawet gdyby mój kolega był przekonany, że nasze zajęcia są poprawnie napisane, twierdzenia tutaj nadal by się przydały. Zostaną dodane nowe klasy, które mogą nie przetestować dla null, a ta metoda może oznaczać te błędy dla nas.

  4. Podczas tworzenia należy zawsze włączać asercje, nawet jeśli napisany kod nie używa asercji. Mój IDE jest ustawiony na zawsze to zrobić domyślnie dla każdego nowego wykonywalny.

  5. Twierdzenia nie zmieniają zachowania kodu w produkcji, więc mój kolega jest zadowolony, że istnieje sprawdzenie null i że ta metoda będzie działać poprawnie, nawet jeśli metoda equals() jest błędna. Jestem szczęśliwy, ponieważ złapię każdą metodę buggy equals() w rozwoju.

Powinieneś również przetestować swoją politykę twierdzeń, umieszczając tymczasowe twierdzenie, które się nie powiedzie, więc możesz mieć pewność, że zostaniesz powiadomiony za pośrednictwem dziennika plik lub ślad stosu w strumieniu wyjściowym.

 51
Author: MiguelMunoz,
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-11-02 08:47:11

Wiele dobrych odpowiedzi wyjaśniających, co robi słowo kluczowe assert, ale niewielu odpowiada na prawdziwe pytanie: "kiedy powinno się użyć słowa kluczowego assert w prawdziwym życiu?"

Odpowiedź: prawie nigdy .

Twierdzenia, jako pojęcie, są wspaniałe. Dobry kod ma wiele if (...) throw ... stwierdzeń(i ich krewnych, takich jak Objects.requireNonNull i Math.addExact). Jednak niektóre decyzje projektowe znacznie ograniczyły użyteczność assert samo słowo kluczowe .

Pomysł na jazdę assert słowo kluczowe jest przedwczesną optymalizacją, a główną cechą jest możliwość łatwego wyłączenia wszystkich sprawdzeń. W rzeczywistości kontrole assert są domyślnie wyłączone.

[16]}jednak niezwykle ważne jest, aby kontrole niezmiennicze były nadal przeprowadzane w produkcji. Dzieje się tak, ponieważ doskonałe pokrycie testu jest niemożliwe, a cały kod produkcyjny będzie miał błędy, które powinny pomóc zdiagnozować i złagodzić.

Dlatego stosowanie if (...) throw ... powinno być preferowane, tak jak jest to wymagane do sprawdzania wartości parametrów metod publicznych oraz do rzucania IllegalArgumentException.

Czasami można pokusić się o napisanie czeku niezmienniczego, który zajmuje niepożądanie dużo czasu (i jest nazywany na tyle często, że ma znaczenie). Jednak takie kontrole spowolnią testowanie, co również jest niepożądane. Takie czasochłonne kontrole są zwykle zapisywane jako testy jednostkowe. Niemniej jednak czasami może mieć sens użycie assert z tego powodu.

Nie używaj assert po prostu dlatego, że jest czystsza i ładniejsza niż if (...) throw ... (i mówię to z wielkim bólem, bo lubię czyste i ładne). Jeśli po prostu nie możesz się powstrzymać i możesz kontrolować, jak Twoja aplikacja jest uruchamiana, możesz używać assert, ale zawsze włączaj asercje w produkcji./ Align = "left" / Naciskam na adnotację lombok, która sprawi, że assert będzie działać bardziej jak if (...) throw .... Głosuj na to tutaj.

(Rant: twórcy JVM byli bandą okropnych, przedwcześnie optymalizacja koderów. Dlatego słyszysz o tak wielu problemach bezpieczeństwa w wtyczce Java i JVM. Odmówili włączenia podstawowych kontroli i twierdzeń do kodu produkcji, a my nadal płacimy tę cenę.)

 16
Author: Aleksandr Dubinsky,
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-11-14 10:04:57

Oto najczęstszy przypadek użycia. Załóżmy, że włączasz wartość enum:

switch (fruit) {
  case apple:
    // do something
    break;
  case pear:
    // do something
    break;
  case banana:
    // do something
    break;
}
Dopóki zajmujesz się każdą sprawą, nic Ci nie jest. Ale pewnego dnia ktoś doda figę do twojego enum i zapomni dodać ją do Twojej instrukcji switch. Spowoduje to błąd, który może być trudny do złapania, ponieważ efekty będą odczuwalne dopiero po opuszczeniu instrukcji switch. Ale jak tak napiszesz swój switch to możesz go od razu złapać:
switch (fruit) {
  case apple:
    // do something
    break;
  case pear:
    // do something
    break;
  case banana:
    // do something
    break;
  default:
    assert false : "Missing enum value: " + fruit;
}
 11
Author: MiguelMunoz,
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
2014-01-17 07:29:08

Twierdzenia są używane do sprawdzania warunków post-conditions I" should never fail " pre-conditions. Poprawny kod nigdy nie powinien zawieść twierdzenia; kiedy wyzwalają, powinny wskazywać błąd(miejmy nadzieję, że w miejscu, które jest blisko miejsca, w którym znajduje się rzeczywiste miejsce problemu).

Przykładem twierdzenia może być sprawdzenie, czy dana grupa metod jest wywoływana w odpowiedniej kolejności (np. że hasNext() jest wywoływana przed next() w Iterator).

 10
Author: Donal Fellows,
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
2010-05-03 13:17:25

Do czego służy słowo kluczowe assert w Javie?

Spójrzmy na skompilowany kod bajtowy.

Wyciągniemy wniosek, że:

public class Assert {
    public static void main(String[] args) {
        assert System.currentTimeMillis() == 0L;
    }
}

Generuje prawie taki sam bajt jak:

public class Assert {
    static final boolean $assertionsDisabled =
        !Assert.class.desiredAssertionStatus();
    public static void main(String[] args) {
        if (!$assertionsDisabled) {
            if (System.currentTimeMillis() != 0L) {
                throw new AssertionError();
            }
        }
    }
}

Gdzie Assert.class.desiredAssertionStatus() jest true kiedy {[8] } jest przekazywane w linii poleceń, a w przeciwnym razie false.

Używamy System.currentTimeMillis(), aby upewnić się, że nie zostanie zoptymalizowany (assert true; did).

Syntetyczne pole jest generowane tak, że Java musi tylko wywołać Assert.class.desiredAssertionStatus() raz w czasie ładowania, a następnie buforuje wynik. Zobacz też: Jakie jest Znaczenie słowa "statyczny syntetyk"?

Możemy to zweryfikować za pomocą:

javac Assert.java
javap -c -constants -private -verbose Assert.class

W Oracle JDK 1.8.0_45 wygenerowano syntetyczne pole statyczne (Zobacz także: Jakie jest znaczenie "syntetyczne statyczne"?):

static final boolean $assertionsDisabled;
  descriptor: Z
  flags: ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC

Wraz ze statycznym inicjalizatorem:

 0: ldc           #6                  // class Assert
 2: invokevirtual #7                  // Method java/lang Class.desiredAssertionStatus:()Z
 5: ifne          12
 8: iconst_1
 9: goto          13
12: iconst_0
13: putstatic     #2                  // Field $assertionsDisabled:Z
16: return

A główną metodą jest:

 0: getstatic     #2                  // Field $assertionsDisabled:Z
 3: ifne          22
 6: invokestatic  #3                  // Method java/lang/System.currentTimeMillis:()J
 9: lconst_0
10: lcmp
11: ifeq          22
14: new           #4                  // class java/lang/AssertionError
17: dup
18: invokespecial #5                  // Method java/lang/AssertionError."<init>":()V
21: athrow
22: return

Wnioskujemy, że:

  • nie ma poziomu kodu bajtowego wsparcie dla assert: jest to koncepcja języka Java
  • assert może być dobrze emulowany z właściwościami systemowymi -Pcom.me.assert=true, aby zastąpić -ea w wierszu poleceń i throw new AssertionError().
 6
Author: Ciro Santilli 新疆改造中心 六四事件 法轮功,
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-05-23 10:31:36

Przykład ze świata rzeczywistego, z klasy stosu (z twierdzenia w artykułach Javy)

public int pop() {
   // precondition
   assert !isEmpty() : "Stack is empty";
   return stack[--num];
}
 5
Author: Björn,
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
2018-01-19 18:06:45

Oprócz wszystkich świetnych odpowiedzi tutaj, official Java SE 7 programming guide zawiera dość zwięzłą instrukcję użycia assert; z kilkoma dokładnymi przykładami, kiedy używanie twierdzeń jest dobrym (i, co ważne, złym) pomysłem i czym różni się od rzucania WYJĄTKÓW.

Link

 4
Author: Ivan Bartsov,
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
2015-07-08 11:40:10

Twierdzenie pozwala na wykrycie wad w kodzie. Można włączyć assertions do testowania i debugowania, pozostawiając je wyłączone, gdy program jest w produkcji.

Po co twierdzić coś, skoro wiesz, że to prawda? Jest to prawdą tylko wtedy, gdy wszystko działa prawidłowo. Jeśli program ma wadę, może to nie być prawda. Wykrycie tego wcześniej w procesie pozwala wiedzieć, że coś jest nie tak.

Oświadczenie assert zawiera to Oświadczenie wraz z opcjonalnym String wiadomość.

Składnia instrukcji assert ma dwie formy:

assert boolean_expression;
assert boolean_expression: error_message;

Oto kilka podstawowych zasad, które rządzą, gdzie twierdzenia powinny być używane, a gdzie nie powinny być używane. Twierdzenia powinny być użyte dla:

  1. Walidacja parametrów wejściowych metody prywatnej. Nie dla metod publicznych. public metody powinny wyrzucać regularne wyjątki, gdy przekazywane są złe parametry.

  2. W dowolnym miejscu w programie, aby zapewnić ważność fakt, który jest prawie na pewno prawdą.

Na przykład, jeśli jesteś pewien, że będzie to tylko 1 lub 2, możesz użyć twierdzenia takiego jak:

...
if (i == 1)    {
    ...
}
else if (i == 2)    {
    ...
} else {
    assert false : "cannot happen. i is " + i;
}
...
  1. Walidacja warunków post na końcu dowolnej metody. Oznacza to, że po wykonaniu logiki biznesowej można użyć twierdzeń, aby upewnić się, że wewnętrzny stan zmiennych lub wyników jest zgodny z oczekiwaniami. Na przykład metoda, która otwiera gniazdo lub plik, może użyć twierdzenia w koniec, aby upewnić się, że gniazdo lub plik jest rzeczywiście otwarty.

Twierdzenia nie powinny być używane dla:

  1. Walidacja parametrów wejściowych metody publicznej. Ponieważ twierdzenia nie zawsze mogą być wykonywane, należy użyć zwykłego mechanizmu WYJĄTKÓW.

  2. Sprawdzanie ograniczeń na czymś, co jest wprowadzane przez użytkownika. Tak jak wyżej.

  3. Nie należy stosować w przypadku działań niepożądanych.

Na przykład jest to nie jest to właściwe użycie, ponieważ tutaj twierdzenie jest używane jako efekt uboczny wywołania metody doSomething().

public boolean doSomething() {
...    
}
public void someMethod() {       
assert doSomething(); 
}

Jedynym przypadkiem, w którym może to być uzasadnione, jest próba sprawdzenia, czy twierdzenia są włączone w Twoim kodzie:

boolean enabled = false;    
assert enabled = true;    
if (enabled) {
    System.out.println("Assertions are enabled");
} else {
    System.out.println("Assertions are disabled");
}
 4
Author: solomkinmv,
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
2018-06-29 20:58:09

Assert jest Bardzo przydatny przy rozwijaniu. Używasz go, gdy coś po prostu nie może się wydarzyć, jeśli twój kod działa poprawnie. Jest łatwy w użyciu i może pozostać w kodzie na zawsze, ponieważ zostanie wyłączony w prawdziwym życiu.

Jeśli istnieje jakakolwiek szansa, że stan może wystąpić w prawdziwym życiu, musisz się nim zająć.

Podoba mi się, ale nie wiem jak go włączyć w Eclipse / Android / ADT . Wydaje się być wyłączony nawet podczas debugowania. (Jest wątek na ten, ale odnosi się do "Java vm", która nie pojawia się w konfiguracji ADT Run).

 1
Author: John White,
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
2014-02-05 08:33:11

Oto twierdzenie, które napisałem na serwerze dla projektu Hibernate/SQL. Encja miała dwie właściwości efektywnie-boolowskie, nazywane isActive i isDefault. Każdy z nich mógł mieć wartość "Y" lub "N" lub null, która była traktowana jako "N". Chcemy się upewnić, że klient przeglądarki jest ograniczony do tych trzech wartości. Tak więc, w moich seterach dla tych dwóch właściwości, dodałem to twierdzenie:

assert new HashSet<String>(Arrays.asList("Y", "N", null)).contains(value) : value;

Zauważ, co następuje.

  1. Twierdzenie to dotyczy tylko fazy rozwojowej. Jeśli klient wysyła złą wartość, złapiemy to wcześnie i naprawimy to, na długo przed osiągnięciem produkcji. Twierdzenia są dla wad, które można złapać wcześnie.

  2. Twierdzenie to jest powolne i nieefektywne. W porządku. Twierdzenia mogą być powolne. Nie obchodzi nas to, bo to tylko narzędzia rozwoju. Nie spowolni to kodu produkcyjnego, ponieważ asercje zostaną wyłączone. (Są pewne nieporozumienia w tej kwestii, do których dojdę później.) To prowadzi do mojego następnego punkt.

  3. Twierdzenie to nie ma skutków ubocznych. Mogłem przetestować moją wartość przed niezmodyfikowanym statycznym zestawem końcowym, ale ten zestaw pozostałby w produkcji, gdzie nigdy nie zostanie użyty.

  4. Twierdzenie to ma na celu sprawdzenie poprawności działania Klienta. Więc zanim dojdziemy do produkcji, będziemy mieć pewność, że klient działa prawidłowo, dzięki czemu możemy bezpiecznie wyłączyć twierdzenie.

  5. Niektórzy pytają o to: jeśli asercja nie jest potrzebna w produkcji, dlaczego po prostu ich nie wyjmiesz, gdy skończysz? Ponieważ nadal będziesz ich potrzebować, gdy zaczniesz pracować nad następną wersją.

Niektórzy twierdzili, że nigdy nie należy używać twierdzeń, ponieważ nigdy nie można być pewnym, że wszystkie błędy zniknęły, więc trzeba je trzymać nawet w produkcji. Tak więc nie ma sensu używać instrukcji assert, ponieważ jedyną zaletą asserts jest to, że można je wyłączyć. Stąd, zgodnie z to myślenie, należy (prawie) nigdy nie używać twierdzeń. Nie zgadzam się. To z pewnością prawda, że jeśli test należy do produkcji, nie należy używać assert. Ale ten test Nie należy do produkcji. Ten służy do łapania błędu, który prawdopodobnie nigdy nie osiągnie produkcji, więc może być bezpiecznie wyłączony, gdy skończysz.

BTW, mogłem to napisać tak:

assert value == null || value.equals("Y") || value.equals("N") : value;

Jest to w porządku tylko dla trzech wartości, ale jeśli liczba możliwych wartości będzie większa, Wersja HashSet staje się wygodniejsza. Wybrałem wersję HashSet, aby wyrazić swój punkt o wydajności.

 1
Author: MiguelMunoz,
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-05-18 19:23:44

Twierdzenia są domyślnie wyłączone. Aby je włączyć musimy uruchomić program z opcjami -ea (ziarnistość może być różna). Na przykład java -ea AssertionsDemo.

Istnieją dwa formaty użycia twierdzeń:

  1. proste: np. assert 1==2; // This will raise an AssertionError.
  2. lepiej: assert 1==2: "no way.. 1 is not equal to 2"; Spowoduje to wywołanie Asertionerror z wyświetlaną wiadomością i tym samym jest lepsze. Chociaż rzeczywistą składnią jest assert expr1:expr2 gdzie expr2 może być dowolnym wyrażeniem zwracającym wartość, używałem go częściej tylko do drukowania wiadomość.
 1
Author: Chandan Purohit,
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
2018-02-08 22:32:41

Aby podsumować (i dotyczy to wielu języków nie tylko Javy):

"assert" jest używany głównie jako pomoc debugowania przez programistów podczas procesu debugowania. Assert-wiadomości nigdy nie powinny się pojawiać. Wiele języków zapewnia opcję w czasie kompilacji, która spowoduje, że wszystkie "asserts" zostaną zignorowane, aby użyć ich do generowania kodu "produkcyjnego".

"wyjątki" są poręcznym sposobem obsługi wszelkiego rodzaju błędów, niezależnie od tego, czy reprezentują błędy logiczne, ponieważ, jeśli wpadnij w błąd-stan taki, że nie możesz kontynuować, możesz po prostu "wyrzucić je w powietrze", gdziekolwiek jesteś, oczekując, że ktoś inny będzie gotowy do "złapania" ich. Kontrola jest przenoszona w jednym kroku, prosto z kodu, który rzucił wyjątek, prosto na rękawicę łapacza. (A łapacz może zobaczyć pełną ścieżkę połączeń, które miały miejsce.)

Ponadto osoby wywołujące ten podprogram nie muszą sprawdzać, czy podprogram udało się: "jeśli jesteśmy tu teraz, to musiało się to udać, ponieważ w przeciwnym razie spowodowałoby to wyjątek i nie byłoby nas tutaj teraz!" Ta prosta strategia znacznie ułatwia projektowanie kodu i debugowanie.

Wyjątki pozwalają na to, aby Warunki fatal-error były tym, czym są: "wyjątki od reguły."I, aby były obsługiwane przez ścieżkę kodu, która jest również" wyjątkiem od reguły ... "fly ball!"

 0
Author: Mike Robinson,
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-31 18:05:43

Assertion są zasadniczo używane do debugowania aplikacji lub są używane w zastępstwie obsługi wyjątków dla niektórych aplikacji w celu sprawdzenia ważności aplikacji.

Twierdzenie działa w czasie wykonywania. Prosty przykład, który może wyjaśnić całą koncepcję bardzo prosto, jest tutaj - co robi słowo kluczowe assert w Javie? (WikiAnswers).

 0
Author: SBTec,
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
2018-02-07 17:53:33

Zasadniczo, "assert true" przejdzie, a "assert false" zawiedzie. Przyjrzyjmy się jak to będzie działać:

public static void main(String[] args)
{
    String s1 = "Hello";
    assert checkInteger(s1);
}

private static boolean checkInteger(String s)
{
    try {
        Integer.parseInt(s);
        return true;
    }
    catch(Exception e)
    {
        return false;
    }
}
 0
Author: pradeek,
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
2018-02-07 17:59:42

assert to słowo kluczowe. Został wprowadzony w JDK 1.4. Są dwa rodzaje assert s

  1. bardzo proste assert wypowiedzi
  2. proste assert wypowiedzi.

Domyślnie wszystkie polecenia assert nie będą wykonywane. Jeśli instrukcja assert otrzyma false, to automatycznie wywoła błąd twierdzenia.

 -8
Author: pavani,
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
2015-12-23 14:59:15