Exception Handling Concept Simplified in Java



The point where the problem occurs,we may not know what to do with it.At that point we may not continue further,we stop and either resolve the problem in the current context or if we do not sufficient information to take a decision,we hand it over to the higher context.With Exception handling in place,reading writting and debugging code becomes much cleaner as Exceptions clean up error handling code.Instead of checking for a particular error and dealing with it in multiple places,we can handle the Exception in only one place.Whenever an exception is thrown from a code, we need to handle the exception. Handling the exception can be done in two ways:

  1. Using try catch block
  2. Using throws keywords.
Using try-catch block we can handle the exceptions instantly.Any error prone code or sensitive operation should be put inside try catch block. In this post we will look into details of try catch block. By using throws keyword we pass the exception to the caller method to handle or to pass again to the Java's default exception handling. Throws keyword is written in details here.



what if we do not handle an exception:

public class myException{

     public static void main(String []args){
        myFunction(2,2);
        myFunction(2,0);
        myFunction(4,2);
     }
     private static void myFunction(int x,int y){
     int z=0;
     z=(int)x/y;
    
     System.out.println("result of division"+z);
}
}
 
The output of the code:
$javac myException.java
$java -Xmx128M -Xms16M myException
result of division1
Exception in thread "main" java.lang.ArithmeticException: / by zero
at myException.myFunction(myException.java:10)
at myException.main(myException.java:5)
At second case the exception has occurred.As there is no exception handling mechanism , the exception is propagated to the calling function main. Main also does not have any exception handling,as a result the exception is handed over to default handler. Default handler provides the stack trace and terminates the program.so if we handle the exception the execution will not stop in between.

try catch block:
The scope of try is ordinary and the block is preceded by try keyword .try is the place where exception might occur and catch is the place where we catch those exception and handle it.It is always better to write try block for each risky methods.A method thus catches an Exception using combination of try and catch block.The code placed inside of the try and catch is referred as protected code. This approach make code lengthy and not read friendly.Second approach is to put all risky code inside a single try block. This will be readable .It is a developer's choice.However try-catch tries to handle the Exception in the current context.

  • A try block must immediately followed by one or more catch statements and a finally block..
  • There may be one or more lines of code that will generate the Exception.
  • When an exception occurred or thrown inside of the try block, the control immediately  jump to the catch block and the first matching catch block is executed.The remaining statements in the try block are skipped.
  • When an exception is caught and handled by catch block,the execution control does not jump back to the point where the exception occurred i.e the try block.
  • If no matching catch block is found,the exception is un-handled and will propagate to the calling method to default handler and the program will terminate.
  • If no exception is thrown from try block the catch block never get executed, the control goes to finally block(if available) or next line of code to execute.
Each catch clause is similar to a method that takes one and only one argument of a particular type.Sometimes we never use the identifier as the type of the Exception gives us enough information to deal with the Exception,but the identifier must be there.The handler catch block must appear directly after the try block.If the exception is thrown,the Exception handling mechanism goes hunting for the first handler with an argument that matches the type of the Exception.Then it enters into the catch block and the Exception is considered handled. If no matching catch block is found, it still hunts for the matching Exception,Only the matching clause executes. It is not like Switch statement where we need to break to prevent remaining Exceptions from Executing.

Inside try block , there can be many methods or statements generate the same Exception,in that case one handler is enough to catch it.

syntax:
Single catch:

try{
statements that cause exception or Exception object creator
} 
catch(Exception_type obj)
{ 
statements that handles the exception or Exception handler
} 
real time example:

public class myException{

     public static void main(String []args){
        myFunction(2,2);
        myFunction(2,0);
        myFunction(4,2);
     }
     private static void myFunction(int x,int y){
     int z=0;
     try{
         z=(int)x/y;
     }
     catch(ArithmeticException e)
     {
         System.out.println("Can not divide by zero!!");
     }
     System.out.println("result of division"+z);
}
}
The output of the code:
$javac myException.java
$java -Xmx128M -Xms16M myException
case-1
result of division1
case-2
Can not divide by zero!!
result of division0
case-3
result of division2

Also we have one keyword called finally which takes care of the recovery or post exceptional steps:

try catch and finally block:

try{
statements that cause exception or Exception object creator
} 
catch(Exception_type obj)
{
statements that handles the exception or Exception handler
}
finally
{ 
//recovery code or post exception steps 
} 
Multiple catch statements:
This is required when real time we may deal with different exceptions..When an exception is thrown , the exception handler looks through the nearest handler in order they are written to find a proper match.If the handler gets a perfect match the catch block is executed,ignoring the remaining catch blocks.

try{
statements that cause exception or Exception object creator
} 
catch(Exception_type1 obj)
{
statements that handles the exception or Exception handler
}
catch(Exception_type2 obj)
{
statements that handles the exception or Exception handler
}
catch(Exception_type3 obj)
{
statements that handles the exception or Exception handler
}
....
....
....
catch(Exception_typeN obj)
{
statements that handles the exception or Exception handler
}
finally
{ 
//recovery code or post exception steps 
} 
real time example:

public class myMultiCatchException{
    static String a[]={"Hello","Java"};
    static String myString=null; 
    public static void main(String []args){
    try{
    if(a[2].equals("hi"))
   //can change to a[0] to test the second condition 
    System.out.println("hi");
    if (myString.equals("hello"))
    System.out.println("true");
    
    }
    catch(NullPointerException e)
    {
        System.out.println("A null pointer exception is found");
    }  
     catch(ArrayIndexOutOfBoundsException e)
    {
        System.out.println("index out of bound");
    }  
}
}
The output of the code:
$javac myMultiCatchException.java
$java -Xmx128M -Xms16M myMultiCatchException
index out of bound
if we change to a[2] to a[0]
$javac myMultiCatchException.java
$java -Xmx128M -Xms16M myMultiCatchException
A null pointer exception is found
One more example:

public class myMultiCatchException{
   public static int j;
   public static void main(String args[])
   {
       for(int i=0;i<4;i++)
       {
           try{
               switch(i){
                   case 0:
                       int zero=0;
                       j=2/zero;
                       //divide by zero exception
                       break;
                    case 1:
                        int b[]=null;
                        j=b[0];
                        //null pointer exception
                        break;
                    case 2:
                        int[] c=new int[2];
                        j=c[10];
                        //array outofBoundException
                        break;
                    case 3:
                        char ch="java".charAt(10);
                        //String index out of bounds Exception
                        break;
               }
           }
 
           catch(ArithmeticException e)
           {
               System.out.println("can not divide by zero");
           }
           catch(NullPointerException e)
           {
               System.out.println("A null pointer exception has occured");
           }
            catch(ArrayIndexOutOfBoundsException e)
           {
               System.out.println("Array index is out of bound");
           }
           catch(StringIndexOutOfBoundsException e)
           {
               System.out.println("String index is out of bound");
           } 
           
       }
   }
}
The output of the code:
$javac myMultiCatchException.java
$java -Xmx128M -Xms16M myMultiCatchException
can not divide by zero
A null pointer exception has occured
Array index is out of bound
String index is out of bound

While working with multiple catch statement,we need to be careful the order of the Exception class. In case , in the catch statement if a higher (placed higher in the Exception hierarchy) order exception is mentioned before a lower(placed lower in the Exception hierarchy ) order,then the java runtime picks up the higher exception as it has been placed higher in the catch statement or as it appears first. The lower order is ignored.It produces the unreachable code or an error.

public class myMultiCatchException{
   public static int j;
   public static void main(String args[])
   {
       for(int i=0;i<4;i++)
       {
           try{
               switch(i){
                   case 0:
                       int zero=0;
                       j=2/zero;
                       //divide by zero exception
                       break;
                    case 1:
                        int b[]=null;
                        j=b[0];
                        //null pointer exception
                        break;
                    case 2:
                        int[] c=new int[2];
                        j=c[10];
                        //array outofBoundException
                        break;
                    case 3:
                        char ch="java".charAt(10);
                        //String index out of bounds Exception
                        break;
               }
           }
           catch(Exception e)
           {
               System.out.println("An error has occured");
           }
           
           catch(ArithmeticException e)
           {
               System.out.println("can not divide by zero");
           }
           catch(NullPointerException e)
           {
               System.out.println("A null pointer exception has occured");
           }
            catch(ArrayIndexOutOfBoundsException e)
           {
               System.out.println("Array index is out of bound");
           }
           catch(StringIndexOutOfBoundsException e)
           {
               System.out.println("String index is out of bound");
           } 
           
       }
   }
}

See here the Exception the super class is mentioned first in the catch block. As it is placed in the higher in the exception hierarchy the java runtime will always refer to the Exception class even though specific lower order (placed lower in the exception hierarchy). As a result we get errors:
output of the code:
$javac myMultiCatchException.java
myMultiCatchException.java:35: error: exception ArithmeticException has already been caught
catch(ArithmeticException e)
       ^
myMultiCatchException.java:39: error: exception NullPointerException has already been caught
catch(NullPointerException e)
       ^
myMultiCatchException.java:43: error: exception ArrayIndexOutOfBoundsException has already been caught
catch(ArrayIndexOutOfBoundsException e)
      ^
myMultiCatchException.java:47: error: exception StringIndexOutOfBoundsException has already been caught
catch(StringIndexOutOfBoundsException e)
     ^
4 errors
Catch multiple exceptions with single catch statements:
As all the other exceptions are child class of Class Exception so we can catch multiple exceptions with a single catch statement. In that case no further searching happens.once we have given the statement like catch(Exception e) , all exceptions will be trapped here.

public class myMultiCatchException{
    static String a[]={"Hello","Java"};
    static String myString=null; 
    public static void main(String []args){
    try{
    if(a[2].equals("hi"))
    System.out.println("hi");
    if (myString.equals("hello"))
    System.out.println("true");
    
    }
    catch(Exception e)
    {
        System.out.println("An Exception has come");
    }  
  }
}
 
The output of the code:
An Exception has come
With the above example:

public class myMultiCatchException{
   public static int j;
   public static void main(String args[])
   {
       for(int i=0;i<4;i++)
           try{
               switch(i){
                   case 0:
                       int zero=0;
                       j=2/zero;
                       //divide by zero exception
                       break;
                    case 1:
                        int b[]=null;
                        j=b[0];
                        //null pointer exception
                        break;
                    case 2:
                        int[] c=new int[2];
                        j=c[10];
                        //array outofBoundException
                        break;
                    case 3:
                        char ch="java".charAt(10);
                        //String index out of bounds Exception
                        break;
               }
           }
           catch(Exception e)
           {
               System.out.println("An error has occured");
           }
           }
   }
}
       
The output of the code:
$javac myMultiCatchException.java
$java -Xmx128M -Xms16M myMultiCatchException
An error has occurred
An error has occurred
An error has occurred
An error has occurred
As Exception is the base class of all Exception classes ,hence any Exception can be caught with this approach. But we do not get any specific information about the Exception.

public class myMultiCatchException{
   public static int j;
   public static void main(String args[])
   {
       for(int i=0;i<4;i++){
         try{
             switch(i){
             case 0:
                  int zero=0;
                  j=2/zero;//divide by zero 
                  break;
             case 1:
                  int b[]=null;//not initialized
                  j=b[0];//null pointer exception
                  break;
             case 2:
                  int c=new int[2];
                  j=c[10];//Array out of bound Execption
                  break;
             case 3:
                  char ch="Java".chatAt(9);//String index out of bound 
                  break;
                  }
             }
          catch(Exception e)
          {
           System.out.println("In the testcase#"+i);
           System.out.println(e);
          }
   }
}
}
}
 
The output of the code:
$javac myMultiCatchException.java
$java -Xmx128M -Xms16M myMultiCatchException
An error has occured
The message->/ by zero
get more info->java.lang.ArithmeticException: / by zero
An error has occured
The message->null
get more info->java.lang.NullPointerException
An error has occured
The message->10
get more info->java.lang.ArrayIndexOutOfBoundsException: 10
An error has occured
The message->String index out of range: 10
get more info->java.lang.StringIndexOutOfBoundsException: String index out of range: 10
java.lang.ArithmeticException: / by zero
at myMultiCatchException.main(myMultiCatchException.java:10)
java.lang.NullPointerException
at myMultiCatchException.main(myMultiCatchException.java:15)
java.lang.ArrayIndexOutOfBoundsException: 10
at myMultiCatchException.main(myMultiCatchException.java:20)
java.lang.StringIndexOutOfBoundsException: String index out of range: 10
at java.lang.String.charAt(String.java:658)
at myMultiCatchException.main(myMultiCatchException.java:24)
Finally Block
Exception handling is in fact built with try,catch and finally block. However Finally is optional.Irrespective of try and catch block,finally block gets executed. A try will have one finally block.in finally block ,before exiting from a program,we close open files,open connections,free up some resources etc.The finally block of code will always be executed irrespective of an exception has occurred or not.So if we put these closure lines in try or catch, there is no guarantee that these lines will get executed every time. Finally block will be disrupted if an exception occurred inside it or the system.exit is invoked before it.Say we are trying to process a file and the file is not present in the directory. In that case the exception occurred and in finally block we are trying to close the same file which will raise one more exception.

An example for finally block:

public class DemoMyFinally{
    public static void main(String []args){
    int i=0;
    String[] myString={"Hello","Hi","GoodMorning"};
    while(i<4)
     {
        try{
        System.out.println(myString[i]);
        }
        catch(Exception e)
        {
            System.out.println("An Exception occured");
        }
        finally{
            System.out.println("Recovery started");
            i++;
        }
    }
    }
}
The output of the code:
Hello
Recovery started
Hi
Recovery started
GoodMorning
Recovery started
An Exception occured
Recovery started
On java 7 onwards we can use try with single resources ,multiple resources with an or condition using try constructor and multiple catch with or condition.
try with a single resource:
This is applicable for those classes which implement AutoCloseable interface. Like BufferedReader,FileReader,BufferedWritter etc. The resource is passed as an argument to the try block. The corresponding catch block is optional for try. Since these resources implement AutoCloseable interface,as and when try block finishes execution,the resource will be auto closed. If in case any exception occurs , they will be suppressed.We can retrieve these suppressed exception by Throwable.getSuppressed() method.

try(FileInputStream input = new FileInputStream("C:\\MyTest\\MyFile.txt")) {
}
 
try with a multiple resources:Multiple resources needs to be passed in try constructor separated by ;

try(FileInputStream input = new FileInputStream("C:\\MyTest\\MyFile.txt");BufferedInputStream bufferedInput = new BufferedInputStream(input))
{
}
Modified multi catch:
Refer my previous example:

  catch(ArithmeticException e)
           {
               System.out.println("can not divide by zero");
           }
           catch(NullPointerException e)
           {
               System.out.println("A null pointer exception has occured");
           }
            catch(ArrayIndexOutOfBoundsException e)
           {
               System.out.println("Array index is out of bound");
           }
           catch(StringIndexOutOfBoundsException e)
           {
               System.out.println("String index is out of bound");
           } 
  
instead of this we can upgrade catch statement into a single line catch statement where the exceptions are written as or (||) form.

try{
}
catch(ArithmeticException ||NullPointerException||ArrayIndexOutOfBoundsException ||StringIndexOutOfBoundsException)
{
}
  


For an Exception there are six important steps that an exception handler follows:

  1. Find the problem inside try block we refer as hit.
  2. Inform the problem occurrence referred as throw
  3. Receive the problem information in catch block referred as catch
  4. Take corrective actions  for the problem referred as Handle
  5. if there is no corrective action available pass the problem statement to the calling method-referred as propagate till system level to default handler.
  6. Run post condition steps referred as finally.
Exception Handling Concept Simplified in Java Exception Handling Concept Simplified in Java Reviewed by Animesh Chatterjee on September 27, 2018 Rating: 5

No comments:

Powered by Blogger.