Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
Assertion Facility Enabling and Disabling Assertions Programmatically Setting the Assertion Status for a Package and its Subpackages  Previous   Contents   Next 
   
 

Setting the Assertion Status for a Class and its Nested Classes

The following method is used to set assertion status on a per-class basis:

public void setClassAssertionStatus(string className, boolean enabled);

Resetting to the Class Loader Default Assertion Status

The following method clears any assertion status settings associated with a class loader:

public void clearAssertStatus();

Usage Notes

The material contained in this section is not part of the assert specification, instead it is intended to provide information about the use of the facility. In the parlance of the standards community, the information in this section is non-normative.

You will find examples of appropriate and inappropriate use of the assert construct. The examples are not exhaustive and are meant to convey the intended usage of the construct.

Internal Invariants

In general, it is appropriate to frequently use short assertions indicating important assumptions concerning a program's behavior.

In the absence of an assertion facility, many programmers use comments in the following way:
 if (i%3 == 0) {
        ...
    } else if (i%3 == 1) {
        ...
    } else { // (i%3 == 2)
        ...
    }

When your code contains a construct that asserts an invariant, you should change it to an assert. To change the above example (where an assert protects the else clause in a multiway if-statement), you might do the following:
if (i % 3 == 0) {
        ...
    } else if (i%3 == 1) {
        ...
    } else {
        assert i%3 == 2;
        ...
    }

Note, the assertion in the above example may fail if i is negative, as the % operator is not a true mod operator, but computes the remainder, which may be negative.

Control-Flow Invariants

Another good candidate for an assertion is a switch statement with no default case.

For example:
 switch(suit) {
      case Suit.CLUBS:
        ...
        break;

      case Suit.DIAMONDS:
        ...
        break;

      case Suit.HEARTS:
        ...
        break;

      case Suit.SPADES:
        ...
    }

The programmer probably assumes that one of the four cases in the above switch statement will always be executed. To test this assumption, add the following default case:
default:
        assert false;

More generally, the following statement should be placed at any location the programmer assumes will not be reached.
 assert false;

For example, suppose you have a method that looks like this:
 void foo() {
        for (...) {
            if (...)
                return;
         }
         // Execution should never reach this point!!!
    }

Replace the final comment with:
assert false;

Note, use this technique with discretion. If a statement is unreachable as defined in (JLS 14.19), you will see a compile time error if you try to assert that it is unreached.

Preconditions, Postconditions, and Class Invariants

While the assert construct is not a full-blown design-by-contract facility, it can help support an informal design-by-contract style of programming.

Preconditions

By convention, preconditions on public methods are enforced by explicit checks inside methods resulting in particular, specified exceptions. For example:
 /**
     * Sets the refresh rate.
     *
     * @param  rate refresh rate, in frames per second.
     * @throws IllegalArgumentException if rate <= 0 or
     *          rate > MAX_REFRESH_RATE.
     */
     public void setRefreshRate(int rate) {
         // Enforce specified precondition in public method
         if (rate <= 0 || rate > MAX_REFRESH_RATE)
             throw new IllegalArgumentException("Illegal rate: " + rate);

         setRefreshInterval(1000/rate);
     }

This convention is unaffected by the addition of the assert construct. An assert is inappropriate for such preconditions, as the enclosing method guarantees that it will enforce the argument checks, whether or not assertions are enabled. Further, the assert construct does not throw an exception of the specified type.

If, however, there is a precondition on a nonpublic method and the author of a class believes the precondition to hold no matter what a client does with the class, then an assertion is entirely appropriate. For example:
  /**
    * Sets the refresh interval (must correspond to a legal frame rate).
    *
    * @param  interval refresh interval in milliseconds.
    */
    private void setRefreshInterval(int interval) {
        // Confirm adherence to precondition in nonpublic method
        assert interval > 0 && interval <= 1000/MAX_REFRESH_RATE;

        ... // Set the refresh interval
    }

 
 
 
  Previous   Contents   Next