Assertions in Java
While writing code, you make assumptions: "this total can never be negative here", "this list is sorted by now". An assertion writes that assumption into the code with the assert keyword. During development and testing, Java checks it, and if it's ever false you learn immediately that your reasoning had a hole. In production, assertions are normally switched off, so they cost nothing. That makes them a tool for catching your own bugs, not for checking user input.
Writing and Enabling an Assertion
public class Percent {
static double percent(int got, int total) {
assert total > 0 : "total must be positive, was " + total;
return got * 100.0 / total;
}
public static void main(String[] args) {
System.out.println(percent(45, 50));
System.out.println(percent(10, 0));
}
}Run normally, assertions are disabled:
java Percent.java90.0
InfinityRun with -ea (enable assertions):
java -ea Percent.java90.0
Exception in thread "main" java.lang.AssertionError: total must be positive, was 0
at Percent.percent(Percent.java:3)
at Percent.main(Percent.java:9)How it works
assert condition : message;means "this must be true here". The message part is optional.- Without
-ea, the line is skipped entirely: the condition isn't even evaluated, sopercent(10, 0)quietly returnsInfinity. - With
-ea, a false condition throwsAssertionError(anError, not anException) with your message.
Assertions vs Exceptions
| Use an assertion for | Use an exception for |
|---|---|
| Things that should be impossible if your code is correct | Things that can really happen: bad input, missing files |
| Internal checks in private methods | Checking arguments of public methods |
| Catching bugs during development and testing | Behavior that must work in production, where assertions are off |
Because assertions can be turned off, never put code with side effects inside them, and never use them to validate input from users or callers:
assert list.remove(item); // wrong: nothing is removed without -ea
boolean removed = list.remove(item); // right: the work always happens
assert removed : "item should have been in the list";Enabling Assertions
| Option | Effect |
|---|---|
java -ea MyApp | Enable assertions in your classes |
java -ea:com.poolstring... MyApp | Enable only in one package and its sub-packages |
java -da MyApp | Disable (the default) |
| IDE run configurations | Usually have a VM options field where you add -ea |
Common Mistakes
Validating public method arguments with assert. In production they're off; throw IllegalArgumentException instead.
Side effects inside the condition. The code won't run when assertions are disabled.
Expecting assertions to run without -ea. They're off by default.
Practice
- Easy: Add an assertion to a method that calculates a discount, asserting the result is never more than the original price. Run with and without
-ea. - Harder: Write a private
sorthelper and assert at the end that the array is sorted. Introduce a bug and confirm the assertion catches it with-ea.
Key Takeaways
Was this tutorial helpful?