Tässä opetusohjelmassa opitaan Java assert -lausekkeesta (Java-väitteet) esimerkkien avulla.
Java-väitteet auttavat havaitsemaan virheitä testaamalla koodin, jonka oletamme olevan totta.
Väite tehdään assert
avainsanalla.
Sen syntaksi on:
assert condition;
Tässä condition
on looginen lauseke, jonka oletamme olevan totta, kun ohjelma suoritetaan.
Ota väitteet käyttöön
Oletuksena väitteet poistetaan käytöstä ja ohitetaan ajon aikana.
Väitteiden käyttöön ottamiseksi käytämme:
java -ea:arguments
TAI
java -enableassertions:arguments
Kun väitteet ovat käytössä ja ehto on true
, ohjelma suorittaa normaalisti.
Mutta jos ehto arvioidaan, false
kun väitteet ovat käytössä, JVM heittää an AssertionError
, ja ohjelma pysähtyy välittömästi.
Esimerkki 1: Java-väite
class Main ( public static void main(String args()) ( String() weekends = ("Friday", "Saturday", "Sunday"); assert weekends.length == 2; System.out.println("There are " + weekends.length + " weekends in a week"); ) )
Tuotos
Viikossa on 3 viikonloppua
Saamme yllä olevan lähdön, koska tässä ohjelmassa ei ole kokoamisvirheitä ja väitteet ovat oletusarvoisesti pois käytöstä.
Kun olet ottanut väitteet käyttöön, saadaan seuraava tulos:
Poikkeus säikeessä "main" java.lang.AssertionError
Toinen väitemenettelyn muoto
assert condition : expression;
Tässä väitemenettelyn muodossa lauseke välitetään AssertionError
objektin rakentajalle . Tällä lausekkeella on arvo, joka näytetään virheen tarkkuussanomana, jos ehto on false
.
Yksityiskohtaista sanomaa käytetään väittämisen epäonnistumisen tietojen kaappaamiseen ja lähettämiseen ongelman vianetsinnän helpottamiseksi.
Esimerkki 2: Java-väite ilmaisuesimerkillä
class Main ( public static void main(String args()) ( String() weekends = ("Friday", "Saturday", "Sunday"); assert weekends.length==2 : "There are only 2 weekends in a week"; System.out.println("There are " + weekends.length + " weekends in a week"); ) )
Tuotos
Poikkeus säikeessä "main" java.lang.AssertionError: Viikossa on vain 2 viikonloppua
Kuten näemme yllä olevasta esimerkistä, lauseke välitetään AssertionError
objektin rakentajalle . Jos oletuksemme on false
ja väitteet ovat käytössä, heitetään poikkeus asianmukaisella viestillä.
Tämä viesti auttaa väittämän epäonnistumisen aiheuttaneen virheen diagnosoinnissa ja korjaamisessa.
Lausunnon käyttöönotto tietyille luokille ja paketeille
Jos emme anna argumentteja väitteen komentorivikytkimille,
java -ea
Tämä mahdollistaa väittämisen kaikissa luokissa paitsi järjestelmäluokissa.
Voimme myös ottaa väitteen käyttöön tietyille luokille ja paketeille argumenttien avulla. Näille komentorivikytkimille voidaan antaa seuraavat argumentit:
Ota väite käyttöön luokan nimissä
Jotta väite voidaan ottaa käyttöön kaikilla pääohjelmamme luokilla,
java -ea Main
Ota vain yksi luokka käyttöön
java -ea:AnimalClass Main
Tämä mahdollistaa väite vain AnimalClass
on Main
ohjelmassa.
Ota väite käyttöön pakettien nimissä
Jos haluat ottaa väitteet käyttöön vain paketille com.animal
ja sen alipaketeille,
java -ea:com.animal… Main
Ota väite käyttöön nimettömissä paketeissa
Väitteen ottaminen käyttöön nimeämättömissä paketeissa (kun emme käytä pakettilausetta) nykyisessä työhakemistossa.
java -ea:… Main
Ota väite käyttöön järjestelmäluokissa
Jotta väite voidaan ottaa käyttöön järjestelmäluokissa, käytämme erilaista komentorivikytkintä:
java -esa:arguments
TAI
java -enablesystemassertions:arguments
Näille kytkimille voidaan antaa samat argumentit.
Poistetaan väitteet
Väitteiden poistamiseksi käytöstä käytämme:
java -da arguments
TAI
java -disableassertions arguments
To disable assertion in system classes, we use:
java -dsa:arguments
OR
java -disablesystemassertions:arguments
The arguments that can be passed while disabling assertions are the same as while enabling them.
Advantages of Assertion
- Quick and efficient for detecting and correcting bugs.
- Assertion checks are done only during development and testing. They are automatically removed in the production code at runtime so that it won’t slow the execution of the program.
- It helps remove boilerplate code and make code more readable.
- Refactors and optimizes code with increased confidence that it functions correctly.
When to use Assertions
1. Unreachable codes
Unreachable codes are codes that do not execute when we try to run the program. Use assertions to make sure unreachable codes are actually unreachable.
Let’s take an example.
void unreachableCodeMethod() ( System.out.println("Reachable code"); return; // Unreachable code System.out.println("Unreachable code"); assert false; )
Let’s take another example of a switch statement without a default case.
switch (dayOfWeek) ( case "Sunday": System.out.println("It’s Sunday!"); break; case "Monday": System.out.println("It’s Monday!"); break; case "Tuesday": System.out.println("It’s Tuesday!"); break; case "Wednesday": System.out.println("It’s Wednesday!"); break; case "Thursday": System.out.println("It’s Thursday!"); break; case "Friday": System.out.println("It’s Friday!"); break; case "Saturday": System.out.println("It’s Saturday!"); break; )
The above switch statement indicates that the days of the week can be only one of the above 7 values. Having no default case means that the programmer believes that one of these cases will always be executed.
However, there might be some cases that have not yet been considered where the assumption is actually false.
This assumption should be checked using an assertion to make sure that the default switch case is not reached.
default: assert false: dayofWeek + " is invalid day";
If dayOfWeek has a value other than the valid days, an AssertionError
is thrown.
2. Documenting assumptions
To document their underlying assumptions, many programmers use comments. Let’s take an example.
if (i % 2 == 0) (… ) else ( // We know (i % 2 == 1)… )
Use assertions instead.
Comments can get out-of-date and out-of-sync as the program grows. However, we will be forced to update the assert
statements; otherwise, they might fail for valid conditions too.
if (i % 2 == 0) (… ) else ( assert i % 2 == 1 : i;… )
When not to use Assertions
1. Argument checking in public methods
Arguments in public methods may be provided by the user.
So, if an assertion is used to check these arguments, the conditions may fail and result in AssertionError
.
Instead of using assertions, let it result in the appropriate runtime exceptions and handle these exceptions.
2. To evaluate expressions that affect the program operation
Do not call methods or evaluate exceptions that can later affect the program operation in assertion conditions.
Let us take an example of a list weekdays which contains the names of all the days in a week.
ArrayList weekdays = new ArrayList(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" )); ArrayList weekends= new ArrayList(Arrays.asList("Sunday", "Saturday" )); assert weekdays.removeAll(weekends);
Here, we are trying to remove elements Saturday
and Sunday
from the ArrayList weekdays.
Jos väite on käytössä, ohjelma toimii hyvin. Jos väitteet poistetaan käytöstä, luettelon elementtejä ei kuitenkaan poisteta. Tämä voi johtaa ohjelman epäonnistumiseen.
Määritä sen sijaan tulos muuttujalle ja käytä sitten tätä muuttujaa väittämiseen.
ArrayList weekdays = new ArrayList(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" )); ArrayList weekends= new ArrayList(Arrays.asList("Sunday", "Saturday" )); boolean weekendsRemoved = weekdays.removeAll(weekends); assert weekendsRemoved;
Tällä tavoin voimme varmistaa, että kaikki viikonloput poistetaan arkipäivistä riippumatta siitä, onko väite käytössä tai poistettu käytöstä. Tämän seurauksena se ei vaikuta ohjelman toimintaan tulevaisuudessa.