Saturday, June 28, 2008

Asserions in Java? Assertions vs Exception? Its usage?


Asserions in Java? Assertions vs Exception? Where to Use & Where NOT?

Assertion in Java

An assertion is a special statement which contains one boolean expression and if that boolean expression returns 'false' then the program throws an AssertionError which is an unchecked exception and it normally terminates the current program/application.

This boolean expression is normally used to verify our assumptions which we used while designing our application. Thus, assertions can be used to write correct programs i.e., the programs which run in accordance with their specifications. Assertions can be easily enabled or disabled (by defauly they are disabled) and this greatly helps improving the maintainability of the application.

An assertion statement can have two forms in Java:-

  • assert BooleanExpression; - AssertionError is thrown if BooleanExpression is false.
  • assert BooleanExpression : ExpressionReturningSomeValue; - in this case the returned value of ExpressionReturningSomeValue is paased to the constructor of the AssertionError class, which is inturn used to provide a String representation of this value as the detailed error message which caused this AssertionError. Remember that the second expression should should always return some value, so we can't use a method call whose return type is void. For all other return types (separate ones for all primitive types and Object type for all reference types and Arrays) the AssertionError class has separate overloaded constructors which are called based on the type of the passed parameter.

Where assertions should NOT be used?

Assertions should never be a part of the implementation of some functionality of the application. They should only be used to verify the assumptions - just to be sure that whatever we assumed while desinging the solution is actually valid in practical as well. Below are few situations where you may get tempted to use assertions, but you should NOT use them:-
  • Do NOT use assertions to implement any application functionality - enabling/disbaling them may cause servere damage to the state of the application and its usability.
  • Do NOT use assertions for argument checking of public methods - public methods represent the public interface of the underlying class to the outside world and the methods should always behave the same. If we use assertions for argument checking then enabling or disabling assertions may change the behavior of the method dramatically, which is of course highly undesirable. In addition, using assertions in such cases won't give us actual cause of the error as it can only throw AssertionError (with a message) and it's obviously not as good as getting the actual cause like IndexOutOfBoundsException, NullPointerException, IllegalArgumentException, etc., which we will otherwise get if we check the arguments without using assertions.

Where to use Assertions?

As we know that assertions should be used to test the assumptions so that we can guarantee a correct program. Hence, they should be used at the places where the execution assumes something and proceeds accordingly. Few of such scenarios are:-
  • Implementing Pre-conditions - assertions can be used to effectively implement pre-conditions. A pre-condition means something which must be true at the time of invokation of a method (otherwise the method may go erratic). An example of such a pre-condition can be checking whether the current thread holds (or doesn't hold) a lock on an object before the thread actually executes a method.
  • Implementing Post-Conditions - similar to Pre-Conditions, these are the assumptions which are expected to be true once the control returns from a method. Assertions can be used effectively to check if it's actually as per the assumption or not. If not then it's better to stop the execution and terminate the application as proceeding further in such a scenario may lead the application to an inconsistent state.
  • Implementing Class Invariants - assetions can be used effectively to check if the assumed relationship between various members of a class is intact or not. This especially helps when an instance is in transition from one consistent state to another and using an assertion to confirm before proceeding further will reduce the possibility of having the application in an inconsistent state.

Assertion vs Exception

We just discussed that assertions should be used to verify the assumptions so that we can guarantee that the application always executes complying with the specifications. Thus we see that assertion is basically a mechanism which helps us writing correct programs. Whereas Exception is a mechanism of checking if the implementation is executing without any expected or unexpected errors or not. So, we see that exceptions are basically used for handling even the unforseen conditions during the execution of an application in a better way and hence using exceptions effectively results into a robust application.

Just visualize the difference between something being correct and something being robust. 'correct' obviously means that whenever the application runs, it runs correctly in accordance with specs whereas 'robust' means whenever the application encounters an error condition either expected in case of checked expection OR unexpected in case of unchecked exceptions, it always handles the execution in a controlled way - either by ignroing the exception or by handling the exception (maybe by saving the state and terminating gracefully).

Therefore, we see that assertions and exceptions are not rivals. In fact they are complimentary to each other and an effective combination of both can ensure the development of a correct and robust application.



Share/Save/Bookmark


2 comments:

Anonymous said...

good

Sandeep Bhandari said...

assertThat is more generic in nature than assertTrue or assertEquals but assertThat is lacks the purpose in its name.
Thanks
Junit assert example