Friday, December 12, 2008

Using assert

Using assert

Java 2, version 1.4 added a new keyword to Java: assert. It is used during program development to create an assertion, which is a condition that should be true during the execution of the program. For example, you might have a method that should always return a positive integer value. You might test this by asserting that the return value is greater than zero using an assert statement. At run time, if the condition actually is true, no other action takes place. However, if the condition is false, then an AssertionError is thrown. Assertions are often used during testing to verify that some expected condition is actually met. They are not usually used for released code.

 

The assert keyword has two forms. The first is shown here.

 

assert condition;

 

Here, condition is an expression that must evaluate to a Boolean result. If the result is true, then the assertion is true and no other action takes place. If the condition is false, then the assertion fails and a default AssertionError object is thrown.

 

The second form of assert is shown here.

 

assert condition : expr;

 

In this version, expr is a value that is passed to the AssertionError constructor. This value is converted to its string format and displayed if an assertion fails. Typically, you will specify a string for expr, but any non-void expression is allowed as long as it defines a reasonable string conversion.

 

Here is an example that uses assert. It verifies that the return value of getnum( ) is positive.

 

// Demonstrate assert.

class AssertDemo {

static int val = 3;

// Return an integer.

static int getnum() {

return val--;

}

public static void main(String args[])

{

int n;

for(int i=0; i < 10; i++) {

n = getnum();

assert n > 0; // will fail when n is 0

System.out.println("n is " + n);

}

}

}

 

Programs that use assert must be compiled using the -source 1.4 option. For example, to compile the preceding program, use this line:

 

javac -source 1.4 AssertDemo.java

 

To enable assertion checking at run time, you must specify the -ea option. For example, to enable assertions for AssertDemo, execute it using this line.

 

java -ea AssertDemo

 

After compiling and running as just described, the program creates the following output.

n is 3

n is 2

n is 1

 

Exception in thread

"main" java.lang.AssertionError at AssertDemo.main(AssertDemo.java:17)

 

In main( ), repeated calls are made to the method getnum( ), which returns an integer value. The return value of getnum( ) is assigned to n and then tested using this assert statement.

 

assert n > 0; // will fail when n is 0

 

This statement will fail when n equals 0, which it will after the fourth call. When this happens, an exception is thrown. As explained, you can specify the message displayed when an assertion fails. For example, if you substitute

 

assert n > 0 : "n is negative!";

 

for the assertion in the preceding program, then the following ouptut will be generated.

n is 3

n is 2

n is 1

 

Exception in thread

"main" java.lang.AssertionError: n is negative! At AssertDemo.main(AssertDemo.java:17)

 

One important point to understand about assertions is that you must not rely on them to perform any action actually required by the program. The reason is that normally, released code will be run with assertions disabled. For example, consider this variation of the preceding program.

 

// A poor way to use assert!!!

class AssertDemo {

// get a random number generator

static int val = 3;

// Return an integer.

static int getnum() {

return val--;

}

public static void main(String args[])

{

int n = 0;

for(int i=0; i < 10; i++) {

assert (n = getnum()) > 0; // This is not a good idea!

System.out.println("n is " + n);

}

}

}

 

In this version of the program, the call to getnum( ) is moved inside the assert statement. Although this works fine if assertions are enabled, it will cause a malfunction when assertions are disabled because the call to getnum( ) will never be executed! In fact, n must now be initialized, because the compiler will recognize that it might not be assigned a value by the assert statement.

 

Assertions are a good addition to Java because they streamline the type of error checking that is common during development. For example, prior to assert, if you wanted to verify that n was positive in the preceding program, you had to use a sequence of code similar to this:

 

if(n < 0) {

System.out.println("n is negative!");

return; // or throw an exception

}

 

With assert, you need only one line of code. Furthermore, you don't have to remove the assert statements from your released code.

 

Assertion Enabling and Disabling Options

When executing code, you can disable assertions by using the -da option. You can enable or disable a specific package by specifying its name after the -ea or -da option.

 

For example, to enable assertions in a package called MyPack, use -ea:MyPack

 

To disable assertions in MyPack use -da:MyPack

 

To enable or disable all subpackages of a package, follow the package name with three dots. For example, -ea:MyPack...

 

You can also specify a class with the -ea or -da option. For example, this enables AssertDemo individually.

 
-ea:AssertDemo

No comments: