Programiranje

Kako uporabljati trditve v Javi

Pisanje programov, ki delujejo pravilno med izvajanjem, je lahko zahtevno. To je zato, ker so naše predpostavke o tem, kako se bo naša koda obnašala, ko se izvrši, pogosto napačne. Uporaba Java-ovih trditev je eden od načinov, da preverite, ali je vaša programska logika zdrava.

Ta vadnica predstavlja trditve Java. Najprej boste izvedeli, kaj so trditve in kako jih določiti in uporabiti v svoji kodi. Nato boste odkrili, kako s trditvami uveljaviti predpogoje in popogoje. Na koncu boste primerjali trditve z izjemami in ugotovili, zakaj v kodi potrebujete oboje.

prenos Prenesite kodo Prenesite izvorno kodo za primere v tej vadnici. Ustvaril Jeff Friesen za JavaWorld.

Kaj so trditve Java?

Pred JDK 1.4 so razvijalci pogosto uporabljali komentarje za dokumentiranje predpostavk o pravilnosti programa. Pripombe pa so kot mehanizem za preizkušanje in odpravljanje napak predpostavk neuporabne. Prevajalnik prezre komentarje, zato jih ni mogoče uporabiti za odkrivanje napak. Razvijalci tudi pogosto ne posodabljajo komentarjev pri spreminjanju kode.

V JDK 1.4 so bile trditve uvedene kot nov mehanizem za preizkušanje in odpravljanje napak predpostavk o naši kodi. V bistvu, trditve so sestavljive entitete, ki se izvajajo med izvajanjem, ob predpostavki, da ste jih omogočili za preizkušanje programov. Trditve lahko programirate tako, da vas obvestijo o napakah, kjer se napake pojavijo, kar močno zmanjša čas, ki bi ga sicer porabili za odpravljanje napak pri neuspešnem programu.

Trditve se uporabljajo za kodifikacijo zahtev, zaradi katerih je program s preskušanjem pravilen ali ne pogoji (Logični izrazi) za resnične vrednosti in obveščanje razvijalca, če so takšni pogoji napačni. Uporaba trditev lahko močno poveča vaše zaupanje v pravilnost kode.

Kako napisati trditev v Javi

Trditve se izvajajo prek trditi izjava in java.lang.AssertionError razred. Ta izjava se začne s ključno besedo trditi in se nadaljuje z logičnim izrazom. Izražen je skladenjsko na naslednji način:

trditi BooleanExpr;

Če BooleanExpr oceni na true, nič se ne zgodi in izvajanje se nadaljuje. Če izraz oceni na false, AssertionError je instantiran in vržen, kot je prikazano v seznamu 1.

Seznam 1:AssertDemo.java (različica 1)

javni razred AssertDemo {public static void main (String [] args) {int x = -1; trdi, da je x> = 0; }}

Trditev v seznamu 1 kaže na prepričanje razvijalca, da ta spremenljivka x vsebuje vrednost, ki je večja ali enaka 0. Vendar pa očitno ni tako; trditi Izvedba izjave povzroči vržen AssertionError.

Sestavi seznam 1 (javac AssertDemo.java) in ga zaženite z omogočenimi trditvami (java -ea AssertDemo). Upoštevati morate naslednje rezultate:

Izjema v niti "main" java.lang.AssertionError pri AssertDemo.main (AssertDemo.java:6)

To sporočilo je nekoliko skrivnostno, saj ne ugotavlja, kaj je povzročilo AssertionError biti vržen. Če želite bolj informativno sporočilo, uporabite trditi izjava, izražena spodaj:

trditi BooleanExpr : ekspr;

Tukaj, ekspr je kateri koli izraz (vključno s klicem metode), ki lahko vrne vrednost - metode z a praznino vrsta vrnitve. Uporabni izraz je nizovna literala, ki opisuje razlog za napako, kot je prikazano v seznamu 2.

Seznam 2:AssertDemo.java (različica 2)

javni razred AssertDemo {public static void main (String [] args) {int x = -1; trdi, da je x> = 0: "x <0"; }}

Sestavi seznam 2 (javac AssertDemo.java) in ga zaženite z omogočenimi trditvami (java -ea AssertDemo). Tokrat morate opaziti naslednji nekoliko razširjeni izhod, ki vključuje razlog za vržen AssertionError:

Izjema v niti "main" java.lang.AssertionError: x <0 pri AssertDemo.main (AssertDemo.java:6)

Na primer, tek AssertDemo brez -ea Možnost (omogoči trditve) ne povzroči izpisa. Ko trditve niso omogočene, se ne izvršijo, čeprav so še vedno prisotne v datoteki razreda.

Predpogoji in postpogoji

Trditve preizkušajo predpostavke programa s preverjanjem, da niso kršeni njegovi različni predpogoji in postpogoji, in razvijalca opozorijo, ko pride do kršitve:

  • A predpogoj je pogoj, ki mora biti pred izvajanjem nekega zaporedja kod ovrednoten kot true. Predpogoji zagotavljajo, da kličoči spoštujejo pogodbe s klicatelji.
  • A postkondicija je pogoj, ki se mora po izvedbi nekega zaporedja kod ovrednotiti na true. Postpogoji zagotavljajo, da klicatelji spoštujejo pogodbe s klicatelji.

Predpogoji

Predpostavke lahko uveljavite v javnih konstruktorjih in metodah tako, da izrecno preverite in po potrebi vržete izjeme. Za metode zasebnih pomočnikov lahko uveljavite predpogoje z podajanjem trditev. Razmislite o seznamu 3.

Seznam 3:AssertDemo.java (različica 3)

uvoz java.io.FileInputStream; uvoz java.io.InputStream; import java.io.IOException; class PNG {/ ** * Ustvarite primerek PNG, preberite določeno datoteko PNG in jo dešifrirajte v ustrezne strukture. * * @param filespec pot in ime datoteke PNG za branje * * @throw NullPointerException, ko filespec je * nič * / PNG (String filespec) vrže IOException {// Uveljavi predpogoje v ne-zasebnih konstruktorjih in // metodah. če (filespec == null) vrže novo NullPointerException ("filespec je null"); poskusite (FileInputStream fis = nov FileInputStream (filespec)) {readHeader (fis); }} private void readHeader (InputStream is) vrže IOException {// Potrdite, da je predpogoj izpolnjen v zasebnih // pomožnih metodah. trdi, da je! = null: "ničelna vrednost je posredovana je"; }} javni razred AssertDemo {public static void main (String [] args) vrže IOException {PNG png = new PNG ((args.length == 0?? null: args [0]); }}

The PNG razred v seznamu 3 je minimalni začetek knjižnice za branje in dekodiranje slikovnih datotek PNG (prenosne omrežne grafike). Konstruktor izrecno primerja filespec s nič, metanje NullPointerException ko ta parameter vsebuje nič. Bistvo je uveljaviti predpogoj, da filespec ne vsebujejo nič.

Ni primerno navesti uveljavi filespec! = null; ker predpogoj, omenjen v konstruktorjevem Javadocu, ne bi bil (tehnično) spoštovan, če bi bile trditve onemogočene. (Pravzaprav bi bilo počaščeno, ker FileInputStream () bi vrgel NullPointerException, vendar ne smete biti odvisni od nedokumentiranega vedenja.)

Vendar trditi je primerno v okviru zasebnega readHeader () pomočnik, ki bo sčasoma dokončan za branje in dekodiranje 8-bajtne glave datoteke PNG. Predpogoj, da je vedno se posreduje, neveljavna vrednost bo vedno držala.

Postpogoji

Postpogoji so običajno podani s trditvami, ne glede na to, ali je metoda (ali konstruktor) javna ali ne. Razmislite o seznamu 4.

Seznam 4:AssertDemo.java (različica 4)

javni razred AssertDemo {public static void main (String [] args) {int [] array = {20, 91, -6, 16, 0, 7, 51, 42, 3, 1}; razvrsti (matrika); za (element int: matrika) System.out.printf ("% d", element); System.out.println (); } private static boolean isSorted (int [] x) {for (int i = 0; i x [i + 1]) return false; vrni res; } zasebna statična void sort (int [] x) {int j, a; // Za vse celoštevilske vrednosti, razen skrajno leve vrednosti ... for (int i = 1; i 0 && x [j - 1]> a) {// Premik leve vrednosti - x [j - 1] - en položaj na desni - // x [j]. x [j] = x [j - 1]; // Posodobi položaj vstavitve na prvotni položaj premaknjene vrednosti // (en položaj v levo). j--; } // vstavite a v položaj vstavitve (ki je bodisi začetni položaj vstavka // bodisi končni položaj vstavka), kjer je a večje od // ali enako vsem vrednostim na njegovi levi. x [j] = a; } assert isSorted (x): "matrika ni razvrščena"; }}

Seznam 4 predstavlja a razvrsti () pomožna metoda, ki uporablja razvrstitev vstavitve algoritem za razvrščanje polja celoštevilskih vrednosti. Uporabil sem trditi preveriti postkondicijo x razvrščeni prej razvrsti () se vrne klicatelju.

Primer v seznamu 4 prikazuje pomembno značilnost trditev, ki je, da so običajno drage za izvedbo. Zaradi tega so trditve v proizvodni kodi običajno onemogočene. Na seznamu 4 isSorted () mora pregledati celotno matriko, kar je v primeru dolgega polja lahko dolgotrajno.

Trditve v primerjavi z izjemami v Javi

Razvijalci s trditvami dokumentirajo logično nemogoče situacije in zaznavajo napake v svoji programski logiki. Med izvajanjem omogočena trditev razvijalca opozori na logično napako. Razvijalec preoblikuje izvorno kodo, da popravi logično napako, nato pa to kodo znova prevede.

Razvijalci uporabljajo Java-ov izjemen mehanizem za odziv na napake pri izvajanju, ki niso usodne (npr. Zmanjka pomnilnika), ki jih lahko povzročijo dejavniki okolja, na primer datoteka, ki ne obstaja, ali slabo napisana koda, na primer poskus deljenja z 0. Pogosto se napiše obravnavalec izjeme, da se natančno opomore od napake, da se lahko program še naprej izvaja.

Trditve niso nadomestilo za izjeme. V nasprotju z izjemami trditve ne podpirajo obnovitve napak (trditve običajno ustavijo izvajanje programa takoj -AssertionError ni namenjen ulovu); pogosto so onemogočeni v proizvodni kodi; in običajno ne prikažejo uporabniku prijaznih sporočil o napakah (čeprav to ni težava z trditi). Pomembno je vedeti, kdaj uporabiti izjeme in ne trditve.

Kdaj uporabiti izjeme

Recimo, da ste napisali sqrt () metoda, ki izračuna kvadratni koren argumenta. V nekompleksnem kontekstnem številu je nemogoče vzeti kvadratni koren negativnega števila. Zato uporabite trditev za neuspeh metode, če je argument negativen. Upoštevajte naslednji fragment kode:

javni dvojni sqrt (dvojni x) {assert x> = 0: "x je negativen"; // ...}

Neprimerno je uporabljati trditev za potrditev argumenta v tem javnosti metoda. Trditev je namenjena odkrivanju napak v programski logiki in ne zaščiti metode pred napačnimi argumenti. Poleg tega, če so trditve onemogočene, ni mogoče rešiti problema negativnega argumenta. Bolje je vrniti izjemo, kot sledi:

javni dvojni sqrt (dvojni x) {if (x <0) vrže novo IllegalArgumentException ("x je negativen"); // ...}

Razvijalec se lahko odloči, da bo program obravnaval izjemo nezakonitega argumenta ali pa jo preprosto razširi iz programa, kjer orodje, ki izvaja program, prikaže sporočilo o napaki. Ko prebere sporočilo o napaki, lahko razvijalec popravi katero koli kodo, ki je privedla do izjeme.

Morda ste opazili neznatno razliko med trditvijo in logiko zaznavanja napak. Preskusi trditve x> = 0, medtem ko logični testi zaznavanja napak x <0. Trditev je optimistična: domnevamo, da je argument v redu. V nasprotju s tem je logika zaznavanja napak pesimistična: domnevamo, da argument ni v redu. Trditve dokumentirajo pravilno logiko, izjeme pa nepravilno vedenje med izvajanjem.

V tej vadnici ste se naučili, kako s trditvami dokumentirati pravilno programsko logiko. Spoznali ste tudi, zakaj trditve ne nadomeščajo izjem, in videli ste primer, ko bi bila uporaba izjeme učinkovitejša.

To zgodbo "Kako uporabljati trditve v Javi" je prvotno objavil JavaWorld.

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