# Java: Assertions

## Assertions stop program when "impossible" situations are detected

Impossible conditions. Program debugging is filled with "impossible" problems ("But that parameter can't possibly be null here"). If you're lucky, the problem is detected immediately in some way you can easily diagnose. If not, the error may propogate thru the program, finally crashing, but so far from the original bug that diagnosis is difficult. Even worse, the bug may not produce visible symptoms until after it has altered permanent data. Assert statements provide an easy means of checking for impossible conditions, with little or no runtime cost.

Programmer, not user problems. The purpose or asserts is to detect programming errors, and they should not be used in the case of erroneous user input or actions.

Crash as quickly as possible. Discovering bugs as early as possible is good. Every program starts with bugs, and the debugging process is faster and simpler when the bugs are detected early. It's better to discover a problem at compile time than at run time, and it's better to discover a run-time bug as early as possible. Often a run-time bug doesn't cause an immediate, visible, disaster. Instead, the consequences of the bug distort the following execution, and the bad effects may not become visible for a long time. The crippled program may corrupt files or have other bad consequences. Tracing symptoms back to the orginal cause can be a long, tedious process. The goal is to detect bugs as early as possible. Assertions provide a relatively painless way to stop many bugs before they go too far.

## Two forms of the `assert` statement.

Usual form

  An assert statement has two parts separated by a colon. The boolean condition must be true for execution to continue. If it is false, an `AssertionError` is thrown, which terminates execution and display the message string. Some examples.

      assert jobQueue.size() == 0 : "processB: queue should have been empty.";

      assert connector != null : "merge: Connector null for " + rel;

  When asserts are enabled (more on that below), the assert statement checks the condition (queue empty, connector is not null, etc) which must be true for the program to function correctly.. If it's true, execution continues. If it's null, an exception containing the message is thrown. This message is for the programmer, so it doesn't have to be user friendly. I typically include the name of the method and sometimes other information that will help make sense of the error.

Abbreviated form

  The simplest form the `assert` statement specifies only a boolean expression that must be true. This is ok when there's not much to say, or the likelyhood of failing seems so remote it isn't worth the extra typing.

      assert n > 0;

## Enabling assertions at runtime

Assertion checking defaults to off at runtime, unfortunately. You should always turn them on.

### JVM runtime `-enableassertions` (`-ea`) option

Command | Effect
--- | ---
`java MyProg` | Assert statements are removed by class loader.
`java -enableassertions MyProg` | Assert statements are executed.
`java -ea MyProg` | Short form for allowing assertions.

It's also possible to enable/disable assertion checking at runtime for individual classes or for library routines, but that level of control is not useful for most purposes.

### Turning runtime assertion checking on in NetBeans 4.0

See NetBeans IDE.

### Should runtime assertion checking default on?

1. Some argue that a production program should not have the overhead of evaluating asserts. Asserts are not slow, but there is some cost. If they are not turned on at at execution time, the class loader actually strips out all the assertion code so they really don't take up any time or memory. But this small amount of time is surely unnoticeable in all but the most critical tasks.
2. The user may be presented with an unfamiliar error message. This seems like an especially bad argument. Does the user really prefer bad results to a strange error message?

Why don't the same people that want assertion checking to default off also want subscript checking to default off?

## Example

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
    /** AssertTest.java - test assertions.
     * @author Fred Swartz
     * @version 1.00 2004-04-04
     *    Compile: javac -source 1.4 AssertTest.java
     *    Run    : java -ea AssertTest
     */

    class AssertTest {
        //=========================================================== main
        public static void main(String[] args) {
            // The following assert statement will stop execution
            //     with a message if assertions are turned on.
            assert false : "Assertions are turned on.";

            // The following statement will only be printed if
            //     assertions are turned off because  assertions
            //     were not allowed at run time by the -ea parameter.
            System.out.println("Assertions are not active.");
        }//end main
    }//end class AssertTest

## More philosophy -- needs to be rewritten

## Test for consistency

One path to early bug detection is to test variables to see if they have expected values. If something is wrong, the program can stop and indicate that an unexpected inconsistency was discovered. Later, when the program is released, this checking may either be disabled to increase speed, or left in if a "crash" is better than uncontrolled bug propogation (usually the case). If the checking code is removed or disabled, it should be reinserted or activated during testing all future updates. Writing checking code can be a major headache, so it isn't done in many cases. The `assert` statement makes testing conditions relatively easy, and allows easy activation or deactivation of some or all of the checking code.

## Check for "impossible" conditions, not bad input

`assert` shouldn't be used for checking for bad input. Input should be checked by code that gives the user a meaningful response and perhaps a chance to correct the input.

Assertions are used to check for things that can't possibly be wrong! This is what bugs are -- things that shouldn't happen do happen because there is something wrong with the code. Assertions are often used in the following cases.

- Check situations which must be true, but aren't obviously so. For example, the result of a complicated calculation must be in a certain range.
- All `switch` statements should have `default` clauses. If this path is impossible, use an assert that will always fail.

      default:
          assert false: "You shouldn't be here!"

- Add an assert where control should never flow, eg, when looking up and returning an entry that "must" be in an array, the code after the loop should never be executed. Put an `assert false: "some message"` there.
- There is less of a need to check conditions which produce immediate execution errors. For example, there is no need to check if an array reference is null when the array is used immediately after that, because a NullPointerException would stop execution. An `assert` would allow a better error message, and you must decide if the extra code is worth the better error diagnostic. In many cases the answer is "no".

## Assertions in Java 1.4

## Java 1.4 default compiler option is no assertions

The `assert` statement was added to Java in version 1.4. The addition of the `assert` keyword may invalidate a few older programs which used it as an identifier. To preserve backward compatibility the `assert` statement can't be used unless an option is specified the compilation (`javac`) commands for the JDK. Java 1.5/5 removed this restriction.

### SDK 1.4 compiler option `-source 1.4`

Command | Effect
--- | ---
`javac MyProg.java` | No assert statements allowed.
`javac -source 1.4 MyProg.java` | Assertions allowed.

## NetBeans 3.6: Enabling Assertions (Java version 1.4 source)

### Enabling assertions for the NetBeans compiler

1. Choose `Tools > Options` menu item.
2. Open `Building > Compiler Types > External Compilation` option panel.
3. Check the `Enable JDK 1.4 Source` property.
4. Repeat the above for the `Internal Compilation` option panel.

### Enabling assertions for the NetBeans executor

1. Choose `Tools > Options` menu item.
2. Open `Debugging and Execution > Execution Types > External Execution` option panel.
3. Check the `Expert > Enable asserts` property.