V tomto tutoriálu se pomocí příkladů seznámíme s příkazem Java assert (Java assertions).
Tvrzení v Javě pomáhají detekovat chyby testováním kódu, který považujeme za pravdivý.
Pomocí assert
klíčového slova je provedeno tvrzení .
Jeho syntaxe je:
assert condition;
Tady condition
je logický výraz, který předpokládáme jako pravdivý, když se program spustí.
Povolení tvrzení
Ve výchozím nastavení jsou kontrolní výrazy za běhu zakázány a ignorovány.
K povolení tvrzení používáme:
java -ea:arguments
NEBO
java -enableassertions:arguments
Pokud jsou tvrzení povolena a podmínka je true
, program se spustí normálně.
Ale pokud se podmínka vyhodnotí, false
dokud jsou povolena tvrzení, JVM hodí AssertionError
a program se okamžitě zastaví.
Příklad 1: Java tvrzení
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"); ) )
Výstup
K dispozici jsou 3 víkendy v týdnu
Získáme výše uvedený výstup, protože tento program nemá žádné chyby kompilace a ve výchozím nastavení jsou tvrzení zakázána.
Po povolení tvrzení dostaneme následující výstup:
Výjimka ve vlákně "main" java.lang.AssertionError
Další forma tvrzení
assert condition : expression;
V této formě výrazu tvrzení je výraz předán konstruktoru AssertionError
objektu. Tento výraz má hodnotu, která se zobrazí jako podrobná zpráva o chybě, pokud je podmínka splněna false
.
Podrobná zpráva se používá k zachycení a přenosu informací o selhání tvrzení, které pomůže při ladění problému.
Příklad 2: Java tvrzení s příkladem výrazu
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"); ) )
Výstup
Výjimka ve vlákně „main“ java.lang.AssertionError: K dispozici jsou pouze 2 víkendy v týdnu
Jak vidíme z výše uvedeného příkladu, výraz je předán konstruktoru AssertionError
objektu. Pokud je náš předpoklad false
a jsou povolena tvrzení, je vyvolána výjimka s příslušnou zprávou.
Tato zpráva pomáhá diagnostikovat a opravit chybu, která způsobila selhání tvrzení.
Povolení tvrzení pro konkrétní třídy a balíčky
Pokud neposkytneme žádné argumenty přepínačům příkazového řádku tvrzení,
java -ea
To umožňuje tvrzení ve všech třídách kromě systémových tříd.
Můžeme také povolit tvrzení pro konkrétní třídy a balíčky pomocí argumentů. Argumenty, které lze poskytnout těmto přepínačům příkazového řádku, jsou:
Povolit tvrzení v názvech tříd
Chcete-li povolit tvrzení pro všechny třídy našeho programu Main,
java -ea Main
Chcete-li povolit pouze jednu třídu,
java -ea:AnimalClass Main
To umožňuje uplatnění pouze AnimalClass
v Main
programu.
Povolit tvrzení v názvech balíčků
Chcete-li povolit tvrzení pouze pro balíček com.animal
a jeho dílčí balíčky,
java -ea:com.animal… Main
Povolit tvrzení v nepojmenovaných balíčcích
Chcete-li povolit tvrzení v nepojmenovaných balíčcích (když nepoužíváme příkaz balíčku) v aktuálním pracovním adresáři.
java -ea:… Main
Povolit tvrzení ve třídách systému
Chcete-li povolit tvrzení ve třídách systému, používáme jiný přepínač příkazového řádku:
java -esa:arguments
NEBO
java -enablesystemassertions:arguments
Argumenty, které lze poskytnout těmto přepínačům, jsou stejné.
Zakázání tvrzení
K deaktivaci tvrzení používáme:
java -da arguments
NEBO
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.
Pokud je tvrzení povoleno, program funguje dobře. Pokud jsou však tvrzení zakázána, prvky ze seznamu se neodstraní. To může mít za následek selhání programu.
Místo toho přiřaďte výsledek proměnné a poté ji použijte k uplatnění.
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ímto způsobem můžeme zajistit, aby byly všechny víkendy odstraněny z pracovních dnů bez ohledu na to, zda je povoleno nebo zakázáno tvrzení. Výsledkem je, že to neovlivní fungování programu v budoucnu.