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");
}
}