Programovanie

Ako používať tvrdenia v Jave

Písanie programov, ktoré správne fungujú za behu, môže byť náročné. Je to tak preto, lebo naše predpoklady o tom, ako sa bude náš kód správať pri spustení, sú často nesprávne. Používanie funkcie výrazov Java je jedným zo spôsobov, ako overiť, či je vaša programovacia logika v poriadku.

Tento návod predstavuje Java tvrdenia. Najprv sa dozviete, čo sú tvrdenia a ako ich určiť a použiť v kóde. Ďalej sa dozviete, ako používať tvrdenia na vynútenie predbežných a dodatočných podmienok. Na záver porovnáte tvrdenia s výnimkami a zistíte, prečo vo svojom kóde potrebujete obe.

stiahnuť Získajte kód Stiahnite si zdrojový kód pre príklady v tejto príručke. Vytvoril Jeff Friesen pre JavaWorld.

Čo sú to tvrdenia Java?

Pred JDK 1.4 vývojári často používali komentáre na zdokumentovanie predpokladov o správnosti programu. Komentáre sú však zbytočné ako mechanizmus na testovanie a ladenie predpokladov. Kompilátor ignoruje komentáre, takže neexistuje spôsob, ako ich použiť na detekciu chýb. Vývojári tiež často neaktualizujú komentáre pri zmene kódu.

V JDK 1.4 boli zavedené tvrdenia ako nový mechanizmus na testovanie a ladenie predpokladov o našom kóde. V podstate, tvrdenia sú kompilovateľné entity, ktoré sa spúšťajú za behu, za predpokladu, že ste im povolili testovanie programu. Môžete naprogramovať tvrdenia, ktoré vás upozornia na chyby, kde sa chyby vyskytujú, a výrazne tak skracujú čas, ktorý by ste inak strávili ladením zlyhávajúceho programu.

Tvrdenia sa používajú na kodifikáciu požiadaviek, ktoré testovaním robia program správnym alebo nesprávnym podmienky (Logické výrazy) pre skutočné hodnoty a upozornenie vývojára, keď sú tieto podmienky nepravdivé. Používanie tvrdení môže výrazne zvýšiť vašu dôveru v správnosť kódu.

Ako napísať tvrdenie v Jave

Tvrdenia sa realizujú prostredníctvom servera tvrdiť vyhlásenie a java.lang.AssertionError trieda. Toto tvrdenie sa začína kľúčovým slovom tvrdiť a pokračuje booleovským výrazom. Vyjadruje sa syntakticky takto:

tvrdiť BooleanExpr;

Ak BooleanExpr vyhodnotí ako pravdivé, nič sa nedeje a vykonávanie pokračuje. Ak je však výraz vyhodnotený ako nepravdivý, AssertionError je inštancovaný a vyhodený, ako je uvedené v zozname 1.

Výpis 1:AssertDemo.java (verzia 1)

public class AssertDemo {public static void main (String [] args) {int x = -1; tvrdiť x> = 0; }}

Tvrdenie v zozname 1 naznačuje vieru vývojára v túto premennú X obsahuje hodnotu, ktorá je väčšia alebo rovná 0. To však zjavne nie je tento prípad; the tvrdiť vykonanie vyhlásenia má za následok vrhnutie AssertionError.

Zostaviť zoznam 1 (javac AssertDemo.java) a spustite ho s povolenými tvrdeniami (java -ea AssertDemo). Mali by ste dodržiavať nasledujúci výstup:

Výnimka vo vlákne „main“ java.lang.AssertionError na serveri AssertDemo.main (AssertDemo.java:6)

Táto správa je trochu záhadná v tom, že neidentifikuje, čo ju spôsobilo AssertionError byť vyhodený. Ak chcete informatívnejšiu správu, použite tvrdiť vyhlásenie vyjadrené nižšie:

tvrdiť BooleanExpr : expr;

Tu, expr je akýkoľvek výraz (vrátane vyvolania metódy), ktorý môže vrátiť hodnotu - nemôžete vyvolať metódu pomocou a neplatný návratový typ. Užitočným výrazom je reťazcový literál, ktorý popisuje dôvod zlyhania, ako je uvedené v zozname 2.

Výpis 2:AssertDemo.java (verzia 2)

public class AssertDemo {public static void main (String [] args) {int x = -1; tvrdiť x> = 0: "x <0"; }}

Zostaviť zoznam 2 (javac AssertDemo.java) a spustite ho s povolenými tvrdeniami (java -ea AssertDemo). Tentokrát by ste mali sledovať nasledujúci mierne rozšírený výstup, ktorý obsahuje aj dôvod vyhodenia AssertionError:

Výnimka vo vlákne "main" java.lang.AssertionError: x <0 v AssertDemo.main (AssertDemo.java:6)

Napríklad pre beh AssertDemo bez -ea Výsledkom možnosti (povoliť tvrdenia) nie je žiadny výstup. Ak tvrdenia nie sú povolené, nevykonajú sa, hoci sú stále v súbore triedy.

Predpoklady a predpoklady

Tvrdenia testujú predpoklady programu overením, že nie sú porušené jeho rôzne predpoklady a dodatočné podmienky, čím vývojára upozornia, keď dôjde k porušeniu:

  • A predpoklad je podmienka, ktorá musí byť vyhodnotená ako pravdivá pred vykonaním nejakej postupnosti kódu. Predpoklady zabezpečujú, aby volajúci dodržiaval svoje zmluvy s volanými.
  • A podmienka je stav, ktorý sa musí vyhodnotiť ako pravdivý po vykonaní nejakej postupnosti kódu. Následné podmienky zaisťujú, že volaní udržiavajú svoje zmluvy s volajúcimi.

Predpoklady

Môžete presadzovať predpoklady na verejných konštruktoroch a metódach vykonaním explicitných kontrol a v prípade potreby vyvolaním výnimiek. Pre metódy súkromných pomocníkov môžete vynútiť predbežné podmienky zadaním tvrdení. Zvážte zoznam 3.

Výpis 3:AssertDemo.java (verzia 3)

import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; trieda PNG {/ ** * Vytvorte inštanciu PNG, prečítajte si zadaný súbor PNG a dekódujte ho * do vhodných štruktúr. * * @param filespec cesta a názov súboru PNG na čítanie * * @vrhá NullPointerException, keď filespec je * nulový * / PNG (String filespec) vrhá IOException {// Vynúti predpoklady v neverejných konštruktoroch a // metódach. if (filespec == null) hodiť novú NullPointerException ("filespec je null"); try (FileInputStream fis = nový FileInputStream (filespec)) {readHeader (fis); }} private void readHeader (InputStream is) throws IOException {// Potvrďte, že predpoklad je splnený v metódach private // helper. tvrdiť je! = null: "hodnota null odovzdaná je"; }} public class AssertDemo {public static void main (String [] args) hodí IOException {PNG png = new PNG ((args.length == 0)? null: args [0]); }}

The PNG triedy v zozname 3 je minimálny začiatok knižnice na čítanie a dekódovanie obrazových súborov PNG (prenosná sieťová grafika). Konštruktér to výslovne porovnáva filespec s nulový, hádzanie NullPointerException keď tento parameter obsahuje nulový. Jedná sa o presadenie predpokladu, že filespec neobsahovať nulový.

Nie je vhodné špecifikovať tvrdiť súborypec! = null; pretože podmienka uvedená v Javadocu konštruktéra by sa (technicky) nedodržala, keby boli tvrdenia zakázané. (V skutočnosti by to bolo poctené, pretože FileInputStream () by hodil NullPointerException, ale nemali by ste byť závislí od neregistrovaného správania.)

Avšak tvrdiť je vhodný v kontexte súkromného readHeader () pomocná metóda, ktorá sa nakoniec dokončí na načítanie a dekódovanie 8-bajtovej hlavičky súboru PNG. Predpoklad, že je vždy, keď bude odovzdané, bude mať nenulovú hodnotu.

Dodatočné podmienky

Postconditions sú zvyčajne špecifikované pomocou tvrdení, bez ohľadu na to, či je metóda (alebo konštruktor) verejná alebo nie. Zvážte zoznam 4.

Výpis 4:AssertDemo.java (verzia 4)

verejná trieda AssertDemo {public static void main (String [] args) {int [] pole = {20, 91, -6, 16, 0, 7, 51, 42, 3, 1}; triediť (pole); pre (int element: array) System.out.printf ("% d", element); System.out.println (); } private static boolean isSorted (int [] x) {for (int i = 0; i x [i + 1]) return false; návrat pravdivý; } private static void sort (int [] x) {int j, a; // Pre všetky celočíselné hodnoty okrem hodnoty úplne vľavo ... pre (int i = 1; i 0 && x [j - 1]> a) {// Posun hodnoty vľavo - x [j - 1] - jedna pozícia napravo - // x [j]. x [j] = x [j - 1]; // Aktualizuje pozíciu vloženia na pôvodnú pozíciu posunutej hodnoty // (o jednu pozíciu vľavo). j--; } // Vložte pozíciu at na vloženie (ktorá je buď počiatočnou pozíciou // pozíciou, alebo konečnou pozíciou vloženia), kde a je väčšie ako // alebo rovnaké ako všetky hodnoty naľavo. x [j] = a; } tvrdiť isSorted (x): "pole nie je zoradené"; }}

Zoznam 4 predstavuje a sort () pomocná metóda, ktorá používa vloženie triediť algoritmus na zoradenie poľa celočíselných hodnôt. Použil som tvrdiť skontrolovať dodatočný stav X sa triedi predtým sort () vráti volajúcemu.

Príklad v zozname 4 demonštruje dôležitú charakteristiku tvrdení, ktorou je to, že ich vykonanie je zvyčajne nákladné. Z tohto dôvodu sú tvrdenia vo výrobnom kóde zvyčajne zakázané. V zozname 4, isSorted () musí prehľadávať celé pole, čo môže byť v prípade dlhého poľa časovo náročné.

Tvrdenia vs. výnimky v Jave

Vývojári pomocou tvrdení dokumentujú logicky nemožné situácie a zisťujú chyby v svojej programovacej logike. Za behu aktivované tvrdenie upozorní vývojára na logickú chybu. Vývojár refaktoruje zdrojový kód, aby opravil logickú chybu, a potom tento kód znova skompiluje.

Vývojári používajú mechanizmus výnimiek Java na reagovanie na nezávažné (napr. Vyčerpanie pamäte) chyby za behu, ktoré môžu byť spôsobené faktormi prostredia, napríklad neexistujúcim súborom, alebo zle napísaným kódom, napríklad pokusom o rozdelenie 0. Obslužný program výnimky je často napísaný tak, aby sa elegantne zotavil z chyby, aby mohol program naďalej bežať.

Tvrdenia nenahrádzajú výnimky. Na rozdiel od výnimiek tvrdenia nepodporujú zotavenie po chybe (tvrdenia zvyčajne okamžite zastavia vykonávanie programu -AssertionError nemá byť chytený); vo výrobnom kóde sú často zakázané; a zvyčajne sa v nich nezobrazujú užívateľsky prívetivé chybové správy (aj keď to nie je problém) tvrdiť). Je dôležité vedieť, kedy použiť skôr výnimky ako tvrdenia.

Kedy použiť výnimky

Predpokladajme, že ste napísali a sqrt () metóda, ktorá počíta druhú odmocninu jeho argumentu. V kontexte zložitých čísel nie je možné brať druhú odmocninu záporného čísla. Preto použijete tvrdenie na zlyhanie metódy, ak je argument záporný. Zvážte nasledujúci fragment kódu:

public double sqrt (double x) {assert x> = 0: "x je záporné"; // ...}

Použiť tvrdenie na overenie argumentu v tomto prípade je nevhodné verejné metóda. Účelom tvrdenia je zistiť chyby v logike programovania a nie chrániť metódu pred chybnými argumentmi. Okrem toho, ak sú tvrdenia zakázané, neexistuje žiadny spôsob, ako sa vysporiadať s problémom negatívnych argumentov. Je lepšie hodiť výnimku nasledovne:

public double sqrt (double x) {if (x <0) throw new IllegalArgumentException ("x is negative"); // ...}

Vývojár sa môže rozhodnúť, že program spracuje výnimku s nelegálnym argumentom, alebo ju jednoducho rozšíri z programu, kde nástroj, ktorý program spúšťa, zobrazí chybové hlásenie. Po prečítaní chybovej správy môže vývojár opraviť akýkoľvek kód, ktorý viedol k výnimke.

Možno ste si všimli jemný rozdiel medzi tvrdením a logikou detekcie chýb. Testy tvrdenia x> = 0, zatiaľ čo logické testy detekcie chýb x <0. Tvrdenie je optimistické: Predpokladáme, že argument je v poriadku. Logika detekcie chýb je naopak pesimistická: Predpokladáme, že argument nie je v poriadku. Tvrdenia dokumentujú správnu logiku, zatiaľ čo výnimky dokumentujú nesprávne chovanie sa za behu.

V tejto príručke ste sa naučili, ako používať tvrdenia na dokumentáciu správnej logiky programu. Dozvedeli ste sa tiež, prečo tvrdenia nenahrádzajú výnimky, a videli ste príklad, kde by použitie výnimky bolo efektívnejšie.

Tento príbeh „Ako používať tvrdenia v Jave“ pôvodne publikoval server JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found