Exception : It is an event of a program, that disrupts the normal flow of execution of instructions of a program.
consider a car suddenly stops while driving due to some problem, to fix it I need to call a mechanic nearby. After examining the fault the mechanic uses a particular tool from the tool-box to fix it.
To handle such exception( problem of car in general ), the runtime system try to call specific methods( mechanic in general ) from a set known as Call Stack ( tool box in general ). It includes a method that contains a block of code which can handle exception. this block of code is known as Exception Handler (tool). The chosen tool is said to catch the exception.
What if mechanic don't have the tool to fix it ? There's a possibility that he might deny.
sometimes this too may happen with the runtime system, where it searches all methods on the call stack thoroughly without finding an appropriate exception handler. In such cases the runtime system eventually terminates.
ADVANTAGES OF EXCEPTIONS :
overview:
Grouping and Differentiating Error types
segmentation of Error handling code and regular code
Propagating Errors up the call stack
1. Grouping and Differentiating Error types
lets consider an example
readfile(){
//open the file;
//determine its size;
//allocate that much memory;
//read the file into memory;
//close the file;
}
here it is possible that function might ignore potential errors.
- error in opening file.
- error in determining length of file
- error in allocating memory
- error in reading file
- error in closing file
for the matter of fact lets insert a bit of code to do error detection, reporting, and handling inside the function.
errorCodeType readFile(){
initialize errorCode = 0;
//open the file;
if (theFileIsOpen) {
//determine the length of the file;
if (gotTheFileLength) {
//allocate that much memory;
if (gotEnoughMemory) {
//read the file into memory;
if (readFailed) {
errorCode = -1;
}
} else {
errorCode = -2;
}
} else {
errorCode = -3;
}
close the file;
if (theFileDidntClose && errorCode == 0) {
errorCode = -4;
} else {
errorCode = errorCode and -4;
}
} else {
errorCode = -5;
}
return errorCode;
}
- What we saw is a messy code which has lost its logical flow. Here Exceptions play there role, Basically they enable you to write the main flow of your code and deal the exceptional cases specifically. You can see the same code in the below snippet but being more specific.
readFile(){
try {
//open the file;
//determine its size;
//allocate that much memory;
//read the file into memory;
//close the file;
} catch (fileOpenFailed) {
errorCode = -1;
} catch (sizeDeterminationFailed) {
errorCode = -2;
} catch (memoryAllocationFailed) {
errorCode = -3;
} catch (readFailed) {
errorCode = -4;
} catch (fileCloseFailed) {
errorCode = -5;
}
}
2. Propagating Errors up the call stack
- Suppose that out of three methods only method1 can handle Exceptions in a good way, we observe that we can propagate(Throw) the work up continuously until the error code finally reaches the specific method which is only interested in it.
we can see this more clearly below
think for a while, What if there's a possibility that using naïve technique may force any of the method duck exceptions when thrown within it? so why not just assign a particular method to worry about it.
NOTE : ducking an exception requires some effort on the part of middleman methods.
- To solve this, Exception Handler comes into effect. Have a look at the snippet below.
method1() {
try {
call method2;
} catch (exception e) {
doErrorProcessing;
}
}
method2() throws exception {
call method3;
}
method3() throws exception {
call readFile;
}
- After analyzing the code, we can clearly see that there's no propagation of exception via listed methods. The fact is, only method1 directly handles the issue.
3.Grouping and Differentiating Error Types
In general lets consider two types of grouping i.e.
- General type of grouping.
- Specific type of grouping.
GENERAL GROUPING :
lets consider an example
//above code
public static void main(String[] args){
int i,j,result=0;
i=0;
j=4;
try{
result = j / i ;
}
catch(Exception e){
System.out.println(e)
}
System.out.println(result);
}
OUTPUT : java.lang.ArithmeticException: / by zero
- what you see in above output is the specific child of exception class.
you can visualize it below
If you mention catch(ArithmeticException e){}
instead of catch(Exception e){}
you will see that the output will be same .So, What is the difference between these two?
Answer to this question is -
In this
catch(Exception e){}
case handler will be able to catch all exceptions as many listed.but In this
catch(ArithmeticException e){}
case you will specifically spot the arithmetic exceptions.
But there are some vulnerabilities in one of the above case !!
- The problem with
catch(Exception e){}
is in effect, by not catching specific errors, the handler must accommodate any possibility. Exception handlers that are too general can make code more error-prone by catching and handling exceptions that weren't anticipated by the programmer and for which the handler was not intended. So it is always a good practice to mention specific Exception Handlers.