Java - Assertions in Java

Assertions in Java are a mechanism used to check whether a particular condition that a programmer expects to be true actually remains true while the program is running. They are mainly useful during development, testing, and debugging because they help identify programming errors early.

An assertion allows a programmer to express an assumption directly in the code. If the assumption turns out to be false, Java throws an AssertionError.

1. What Is an Assertion?

An assertion is a statement that checks a condition that should always be true at a particular point in a program.

The basic syntax is:

assert condition;

For example:

int age = 25;

assert age >= 18;

Here, the programmer expects age to be at least 18. If the condition is true, the assertion passes and the program continues normally.

If the condition is false, an AssertionError is generated.

int age = 15;

assert age >= 18;

The condition age >= 18 is false, so the assertion fails.

2. Assertion with an Error Message

Java also allows a message to be specified when an assertion fails.

The syntax is:

assert condition : message;

Example:

int marks = 35;

assert marks >= 40 : "Marks should be at least 40";

If assertions are enabled and marks is 35, Java throws an AssertionError containing the specified message.

The message can also be created dynamically:

int age = 15;

assert age >= 18 : "Invalid age: " + age;

This can make debugging easier because the error message provides additional information about the failed condition.

3. How Assertions Work

Consider the following program:

public class AssertionExample {
    public static void main(String[] args) {
        int number = 10;

        assert number > 0;

        System.out.println("Number is positive");
    }
}

The assertion checks:

number > 0

Since number is 10, the condition is true and the program continues.

Output:

Number is positive

If the value were:

int number = -10;

the assertion condition would be false. When assertions are enabled, Java would throw an AssertionError.

4. Assertions Are Disabled by Default

One of the most important characteristics of Java assertions is that they are disabled by default.

For example, consider:

public class TestAssertion {
    public static void main(String[] args) {
        int number = -5;

        assert number > 0;

        System.out.println("Program continues");
    }
}

If you run the program normally, the assertion is ignored because assertions are disabled.

Therefore, the program may produce:

Program continues

even though the assertion condition is false.

This behavior is intentional because assertions are primarily intended for development and debugging rather than normal program validation.

5. Enabling Assertions

Assertions can be enabled using the -ea or -enableassertions option when running a Java program.

For example:

java -ea TestAssertion

When assertions are enabled, a failed assertion produces an AssertionError.

For the previous example, the output would be similar to:

Exception in thread "main" java.lang.AssertionError

6. AssertionError

When an assertion fails, Java throws an AssertionError.

For example:

int value = 20;

assert value < 10;

The condition is false, so an AssertionError is generated when assertions are enabled.

It is important to understand that AssertionError is different from an ordinary application exception such as IllegalArgumentException.

Assertions are designed to identify programmer assumptions that should never be violated.

7. Assertions with a Message

A message can provide useful information when an assertion fails.

public class Student {
    public static void main(String[] args) {
        int marks = 25;

        assert marks >= 35 : "Invalid marks: " + marks;

        System.out.println("Valid marks");
    }
}

When assertions are enabled, the failed assertion produces an error containing information such as:

java.lang.AssertionError: Invalid marks: 25

This is particularly useful when debugging larger programs.

8. Using Assertions for Internal Conditions

Assertions are useful when checking conditions that should logically be true inside a program.

For example:

int balance = 5000;

assert balance >= 0 : "Balance cannot be negative";

The programmer expects the balance to remain non-negative. If an internal programming error causes the balance to become negative, the assertion can help identify the problem.

Another example is checking an array index:

int index = 3;
int[] numbers = {10, 20, 30, 40, 50};

assert index >= 0 && index < numbers.length;

System.out.println(numbers[index]);

The assertion documents the programmer's assumption that index must represent a valid position.

9. Assertions in Methods

Assertions can also be used inside methods.

public static int calculate(int number) {
    assert number >= 0 : "Number must not be negative";

    return number * 2;
}

The method assumes that number should not be negative.

Calling:

calculate(10);

satisfies the assertion.

Calling:

calculate(-5);

causes an AssertionError when assertions are enabled.

10. Assertions and Method Preconditions

A precondition describes something that must be true before a particular operation can be performed.

For example:

public static double divide(double a, double b) {
    assert b != 0 : "Divisor cannot be zero";

    return a / b;
}

The programmer expects the divisor to be non-zero.

However, there is an important practical point: assertions should generally not be used to validate user input or external data.

For example, this is not recommended:

assert age >= 18;

if age comes directly from a user and the program must reject users below 18.

Because assertions can be disabled, the validation could disappear completely.

Instead, use normal validation:

if (age < 18) {
    throw new IllegalArgumentException("Age must be at least 18");
}

11. Assertions and User Input

Assertions should not be relied upon for validating information received from external sources.

External sources can include:

  • User input

  • Files

  • Network requests

  • Database records

  • Command-line arguments

  • API responses

For example:

String username = scanner.nextLine();

assert username != null;

This is not an appropriate security or input-validation mechanism because assertions may be disabled.

Normal conditional validation should be used instead:

if (username == null) {
    throw new IllegalArgumentException("Username cannot be null");
}

12. Assertions for Debugging

One of the main purposes of assertions is debugging.

Suppose a program performs several calculations and a value that should never become negative suddenly does.

int total = calculateTotal();

assert total >= 0 : "Total became negative";

If the assertion fails during testing, the programmer immediately knows that an unexpected state has occurred.

This can help locate logical errors before the software is released.

13. Assertions and Testing

Assertions can also be useful during testing because they allow developers to verify assumptions about program behavior.

For example:

int result = 5 * 5;

assert result == 25 : "Incorrect calculation";

The programmer expects the result to be 25.

Another example:

String name = "Java";

assert name.length() == 4;

If a future code modification unexpectedly changes the value, the assertion can identify the problem during testing.

For extensive automated testing, dedicated testing frameworks are generally more appropriate, but Java assertions can still be useful for internal checks.

14. Assertions with Complex Conditions

Assertions can contain more complicated expressions.

int age = 25;
boolean hasLicense = true;

assert age >= 18 && hasLicense :
       "Driver must be an adult with a valid license";

The assertion succeeds only if both conditions are true.

Assertions can also check object state:

class Account {
    private double balance;

    public void withdraw(double amount) {
        balance -= amount;

        assert balance >= 0 : "Account balance became negative";
    }
}

Here, the assertion checks an internal state after the operation.

15. Important Difference Between Assertions and Exceptions

Assertions and exceptions both help identify problems, but they serve different purposes.

Assertions Exceptions
Mainly used for debugging and development Used for handling expected or unexpected runtime problems
Check programmer assumptions Handle errors and exceptional situations
Disabled by default Normally active
Failure produces AssertionError Failure can produce various exception types
Not suitable for user-input validation Suitable for input validation
Useful for internal program conditions Useful for conditions that applications need to respond to

For example, checking an internal assumption:

assert count >= 0;

is appropriate.

Validating user input:

if (count < 0) {
    throw new IllegalArgumentException("Count cannot be negative");
}

is more appropriate.

16. Advantages of Assertions

Assertions provide several benefits:

Early error detection:
They can reveal logical problems during development before they become difficult to diagnose.

Improved debugging:
A failed assertion identifies a condition that violated the programmer's assumption.

Better code documentation:
Assertions communicate assumptions directly within the source code.

Useful for internal state checking:
They can verify that an object's or program's internal state remains valid.

Easy to implement:
Assertions use simple syntax and require little additional code.

17. Limitations of Assertions

Assertions also have limitations.

Disabled by default:
A program cannot depend on assertions for essential validation.

Not suitable for user input:
User input should be validated using normal program logic.

Not a replacement for exception handling:
Assertions do not replace proper exception handling.

Not intended for normal application behavior:
They are primarily designed to identify programming errors and incorrect assumptions.

18. Complete Example

public class AssertionDemo {

    public static void main(String[] args) {

        int marks = 75;

        assert marks >= 0 && marks <= 100 :
                "Marks must be between 0 and 100";

        System.out.println("Marks: " + marks);

        if (marks >= 40) {
            System.out.println("Student has passed");
        } else {
            System.out.println("Student has failed");
        }
    }
}

Here, the assertion checks that the marks fall within the expected range of 0 to 100.

If:

marks = 75;

the assertion succeeds.

If:

marks = 150;

the assertion fails when assertions are enabled.

19. Key Points to Remember

Assertions in Java are primarily used to verify assumptions made by the programmer. They are particularly useful during development and debugging.

The two basic forms are:

assert condition;

and:

assert condition : message;

Assertions are disabled by default and can be enabled using:

java -ea ClassName

When an assertion condition evaluates to false while assertions are enabled, Java throws an AssertionError.

The most important rule is:

Use assertions for internal assumptions and programmer errors; use normal validation and exceptions for conditions that the application is expected to handle.