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.
assert
statement.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.
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;
Assertion checking defaults to off at runtime, unfortunately. You should always turn them on.
-enableassertions
(-ea
) optionCommand | 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.
See NetBeans IDE.
Why don't the same people that want assertion checking to default off also want subscript checking to default off?
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 |
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.
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.
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!"
assert false: "some message"
there.
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".
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.
-source 1.4
Command | Effect |
---|---|
javac MyProg.java | No assert statements allowed. |
javac -source 1.4 MyProg.java | Assertions allowed. |
Tools > Options
menu item.Building > Compiler Types > External Compilation
option panel.Enable JDK 1.4 Source
property.Internal Compilation
option panel.Tools > Options
menu item.Debugging and Execution > Execution Types > External Execution
option panel.Expert > Enable asserts
property.