Tuesday, July 26, 2011

My thoughts on assertions in Java

An assertion is a statement in the JavaTM programming language that enables you to test your assumptions about your program. For example, if you write a method that calculates the speed of a particle, you might assert that the calculated speed is less than the speed of light. 


Oracle gives clear statements where assertions should be used, and in which situation you should avoid using them, however, I used to use assertions in a bit different way.

Assertion is not just a good stuff to check invariants, pre- and postconditions in your code, but it helps for your colleagues by working with your code. You can understand assertions as a kind of security cordon.

They tell a lot for someone who need to fix some bugs or implement some additional feature in or to your code. In many cases they are even more useful than comments (ok, I'm clearly not a fan of comments... just se my corresponding post).

Oracle says: Do not use assertions for argument checking in public methods.
You should follow this for your public API. You really should. But I decided to use assertions in my library internal classes for public methods too. In my team we use assertions in a pretty intensive manner, even in public methods, and for arguments checking, and the helped us a lot. I prefer them over exceptions. You can read in an old post of Joel Spolsky about exceptions:

"... In fact they are significantly worse than goto's:
They are invisible in the source code.
They create too many possible exit points for a function.
..."


Consider the following code snippet:
public class CommandExecutor<T extends Target> {
    private final T targetOfExecution;
    
    public CommandExecutor(T targetOfExecution) {
        assert targetOfExecution != null;

        this.targetOfExecution = targetOfExecution;
        ...
    }

   ...

    public void execute(Command<T> c) {
        // prepare target for command execution
        // do not need to check the targetOfExecution

       // I prefer to get some assertion during development and tests
       // instead of waiting for a runtime np-ex
       assert c != null;

      c.execute( targetOfExecution );

     // do some post operations
    }

}

Assuming that this class is internal to your library, and not part of the private API, the assertion in the constructor will do a favor for you.

Instead of exceptions the assertions can be turned off, so you can combine them with return values to improve the quality of your source.

Further more combining assertion with immutability, the execute method will be more readable, since you can save some null checks.

I would be happy to read your thought on this topic.

No comments:

Post a Comment