Gadgets

Saturday, 7 March 2015

assertions in java


Assertions:-
ð      Introduction
ð     Assert as keyword and identifier
ð     Types of assert statements
ð     Various possible runtime flags
ð     Appropriate and inappropriate use of assertions
ð     AssertionError
Introduction:-
Very common way of debugging is usage of SOPs (System.out.print). But the problem with SOPs statement is after fixing the bug compulsory we have to delete SOP statement otherwise which creates performance problem and disturbs server logging.
Example:-
public class Test
{
               public static void main(String[] args)
               {
                               int i=10;
                               if (i==10)
                               {
                               System.out.println("if i value is correct");
                               for(int j=10;j==i;j--){
                               System.out.println("i value is : "+i);
                               }
                         }
               }
}

In the above example assume first SOP statement is executed and second SOP is not executed then the code is okay up to if(i==10) condition so we need to check code between first SOP and second SOP.
If the code compiles fine and executed final output ‘i value is : 10’ then no need that First SOP, so we should delete that SOPs , we take these types of SOPs to check or debug the code easily.
After code compiles fine then we delete that SOPs otherwise which creates performance problem and disturbs server logging.
To overcome this problem SUN people introduced “assertions” concept in 1.4 version.
The main advantage of assertion is, we use assert keyword instead of SOP statement so no need to delete this assert statement after code compiles fine and fixed debug because based on our requirement we can enable and disable assertions. By default assertions are disable.
Mainly by using assert keyword we can debug code easily.
Usually every application contains development, test, and production so we debug at development and test level only not in production level.
Assert as keyword and identifier:-
Assert keyword introduced in 1.4 version, hence from 1.4 version we can’t use assert as identifier. But before 1.4 version we used assert as identifier.
Example for assert as identifier:-
class Test 
{
               public static void main(String[] args) 
               {
                 int assert=10;
                 System.out.println(assert);
               }
}
 
D:\Java>javac Test.java
Test.java:5: error: as of release 1.4, 'assert' is a keyword, and may not be used as an identifier
We can compile using –source option as shown in the below, here I compiled specific 1.3 version using –source option in java8 version.
It compiles fine but we will get warning and execute fine.
D:\Java>javac -source 1.3 Test.java
warning: [options] bootstrap class path not set in conjunction with -source 1.3
warning: [options] source value 1.3 is obsolete and will be removed in a future
release
Example for assert as keyword:-
class Test 
{
               public static void main(String[] args) 
               {
               int x=10;
               //some code here
               assert(x>10);
               //some code here
               System.out.println("the x value : "+x);
               }
}
D:\Java>java Test
the x value : 10
D:\Java>java -ea Test
Exception in thread "main" java.lang.AssertionError
        at Test.main(Test.java:7)
in the above program we used assert instead of SOP. If we get error at assert statement that mean something wrong in code above assert statement.
“-ea” mean enable assert, while executing we should provide command as “java –ea Test” then only assert will enable otherwise it won’t work.
Types of assert statements:-
There are two types of assert statements
1. Simple version.
2. Augmented version.
Simple version:-
Syntax for simple version:- assert(b)
 ‘b’ should be Boolean type. If ‘b’ is true then our assumption is correct and rest of the code will be executed. If ‘b’ is false then our assumption is wrong and we will get error, we write code wrong somewhere so check that and fix the bug.
Example:-
class Test 
{
               public static void main(String[] args) 
               {
               int x=10;
               //simple version of assert statement 
               assert(x>10);
               //some code here
               System.out.println("the x value : "+x);
               }
}
 
If assert statement is wrong we will get runtime exception so we find that bug and
fix it, if assert statement is correct then code will be execute fine.
 
Augment version:-
We can augment some extra information with AssertionError by using augment.
Syntax for augment version:- assert(b):e;
‘b’ should be Boolean and ‘e’ is any type but we write string most of the times.
 
Example:-
class Test 
{
               public static void main(String[] args) 
               {
               int x=10;
               //augment version of assert statement 
               assert(x>10):"here x should be >10";
               //some code here
               System.out.println("the x value : "+x);
               }
}
We will get exception clearly like below. If ‘b’ is true we will get output, if ‘b’
 is false AssertionError followed by ‘e’.
D:\Java>java -ea Test
Exception in thread "main" java.lang.AssertionError: here x should be >10
at Test.main(Test.java:7) 
Example 2:-
class Test 
{
               public static void main(String[] args) 
               {
               int x=10;
               //simple version of assert statement 
               assert(x>10):m1();
               //some code here
               System.out.println("the x value : "+x);
 
               }
                               public static int m1(){
                               return 999;
               }
}
 
 
D:\Java>java -ea Test
Exception in thread "main" java.lang.AssertionError: 999
        at Test.main(Test.java:7)
in ‘e’ place we taken m1() method instead of string, if assret is false then m1()
will get followed with AssertionError and method return type should not be void 
because it won’t allowed ‘void’.
Various possible runtime flags:-
-ea : to enable assertion in every non-system class(user define class)
-da : to disable assertion in every non-system class(user define class)
-esa : to enable assertion in every system class(pre define class)
-dsa : to disable assertion in every system class(pre define class)
Example:-
D:\Java>java -ea -da -esa -dsa -ea -esa -dsa Test
It will work because the JVM will consider this flags from left to right
In the above example at the end system classes are disabled and non-system classes
are enabled. 
Example:-
Pack1: A.class, B.class, pack2(pack1 contain A,B,pack2)
Pack2: C.class, D.class(pack2 contain C,D)
To enable assertion only B.class :java –ea:pack1.B
To enable assertion both in B and D classes : java –ea:pack1.B –ea:pack1.pack2.D
To enable anywhere in pack1: java –ea:pack1…(3 dots)
To enable assertion anywhere in pack1 except B.class : java –ea:pack1… -da:pack1.B
To enable assertion anywhere in pack1 except pack2 : 
java –ea:pack1… -da:pack1.pack2…
 
We can enable or disable assertions either class wise or package wise also.
Example:-
class Test 
{
               public static void main(String[] args) 
               {
                               boolean assertOn=false;
                               assert(assertOn):assertOn=true;
                               if(assertOn){
                               System.out.println(assertOn);
                               }
               }
}
In the above example:
If assertions are not enable?
We won’t get any output because assert don’t work here
If assertions are enabled?
RuntimeException: AssertionError:true, because assert statement is false.
 
class Test 
{
               public static void main(String[] args) 
               {
                               boolean assertOn=true;
                               assert(assertOn):assertOn=false;
                               if(assertOn){
                               System.out.println(assertOn);
                               }
               }
}
 
In the above example:
If assertions are not enable?
We will get output “assertOn”
If assertions are enabled?
We will get output “assertOn”
 
Appropriate and Inappropriate use of assertions:-
If assert statement is mix with program logic, it is inappropriate because assert
statements are by default disable.
 
Example:-
Improper way:
withdraw(double ammount){
               assert(amount>=100)
                               //process request;
}
In the above example assert statement mix with program logic so assertions are by 
default disable,
while runtime we won’t get correct output.
 
Proper way:
withdraw(double ammount){
if (amount<100)
               throw new illegalequalException();
}
else{
               //process request;
}
 
While performing debugging in our program, if there is any place where the control
is not allowed to reach that is the best place to use assertions.
switch(x){
               case 1:
                               System.out.println("Jan");
                   break;
                               //remaining cases are here
               case 12:
                               System.out.println("Dec");
                   break;
               default:
                               assert(false);
 
It is appropriate for validating private method arguments by using assert because
local person know about whether assertions are enable or disable.It is 
Inappropriate for validating public method arguments by using assert because 
outside person doesn’t know about whether assertions are enabling or disable.
It is inappropriate for validating command line arguments by using assert because
these arguments to main method which is public.
 
               class Test
               {
                               public void m1(int x){
                                              assert(x>10);//inappropriate
                               }
                               private void m2(int x){
                                              assert(x>10);//appropriate
                                  }
       }
AssertionError:-
AssertionError is a child class of Error and it is unchecked, it is raised 
explicitly to indicate that assert statement fails.
Even though it is legal to catch AssertionError but it is not good programming.
Example:-
               class Test
               {
                               public static void main(String[] arg){
                               int x=10;
                               }
                               try{
                                              assert(x>10);
                               }
                               catch(AssertionError ae){
                               System.out.println("not good programming");
                               }
               }