Assertions in Java

Naveen AnamaneniUpdated · 4 min read

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

Percent.java
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:

Terminal
java Percent.java
Terminal output
90.0
Infinity

Run with -ea (enable assertions):

Terminal
java -ea Percent.java
Terminal output
90.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

  1. assert condition : message; means "this must be true here". The message part is optional.
  2. Without -ea, the line is skipped entirely: the condition isn't even evaluated, so percent(10, 0) quietly returns Infinity.
  3. With -ea, a false condition throws AssertionError (an Error, not an Exception) with your message.

Assertions vs Exceptions

Use an assertion forUse an exception for
Things that should be impossible if your code is correctThings that can really happen: bad input, missing files
Internal checks in private methodsChecking arguments of public methods
Catching bugs during development and testingBehavior 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:

Wrong and right
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

OptionEffect
java -ea MyAppEnable assertions in your classes
java -ea:com.poolstring... MyAppEnable only in one package and its sub-packages
java -da MyAppDisable (the default)
IDE run configurationsUsually 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

  1. 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.
  2. Harder: Write a private sort helper and assert at the end that the array is sorted. Introduce a bug and confirm the assertion catches it with -ea.

Quick check: Assertions

4 questions
1Are assertions enabled by default?
2What does a failing assertion throw?
3Should you check user input with assert?
4Why avoid side effects inside an assert?

Key Takeaways

Was this tutorial helpful?

Lesson 236 of 482