Learnerslesson
   JAVA   
  SPRING  
  SPRINGBOOT  
 HIBERNATE 
  HADOOP  
   HIVE   
   ALGORITHMS   
   PYTHON   
   GO   
   KOTLIN   
   C#   
   RUBY   
   C++   




Java - Exceptions

Just imagine, you are asked to enter your gmail Id and Password to login to your Gmail account. But, by mistake you have entered a wrong password. And what if, Gmail exits without giving you a second chance to enter the Password? - It is not acceptable.

Same thing applies for any application. We are allowed to make some sort of mistakes, so that we get a second chance to rectify that. Such mistakes in java are called as Exceptions.

So, the Exceptions should be handled/caught at runtime, and also the entire application should not close due to that Exception.

It is same as your Gmail account doesn't close when someone types a wrong password and at the same time Gmail needs to keep a track on how many times the user is entering a wrong Password.


Exception Hierarchy

java_Exceptions


Exceptions in java are classified into two types :

1. Checked Exception

2. UnChecked Exception


Checked Exception

There are some Exceptions in java which are bound to be checked/handled at compile time. They are called Checked Exception.

Say, for example if we are using 'Class.forName()' to create an Instance of 'Animal' class.


Animal Class

class Animal {

   int noOfLegs;
}


Main Class

class Main{

   public static void main(String[] arg) {

     Class myClass = Class.forName("Animal");
   }
}

Output :


/Main.java:5: error: unreported exception ClassNotFoundException;
             must be caught or declared to be thrown
      Class myClass = Class.forName("Animal");
                   ^
1 error

The above error occurred because there was no try - catch block to catch the Exception.


But what is a try - catch Block?

So, in the above example there is an error in the below line,


Class myClass = Class.forName("Animal");

With the Error message :


unreported exception ClassNotFoundException; must be caught or declared to be thrown.

This means, the above line should be inside a 'try' block, so that whenever an Exception happens the catch block should be able to hold that.


Note : A 'try' block is like a safe zone. So, if any line inside the 'try' block is causing any error, it will be thrown to the catch block and the application will execute as usual.

Let us modify the 'Main' class to see, how we can fix the error with try - catch block.


Main Class

class Main{

   public static void main(String[] arg) {

    try {
     Class myClass = Class.forName("Animal");
    }
    catch(ClassNotFoundException ex) {
     System.out.println(ex.toString());
    }
   }
}

So, as stated we have put


Class myClass = Class.forName("Animal");

inside the try block.


try {
   Class myClass = Class.forName("Animal");
}

And if any Error occurs will be caught by the 'catch' block.


catch(ClassNotFoundException ex) {
      System.out.println(ex.toString());
   }

And, using


System.out.println(ex.toString());

We will be able to display the exception.

So, ClassNotFoundException(As seen in the above example), FileNotFoundException, SQLException are a few checked Exceptions which must be handled inside a try - catch block, else will come up with compile time error.


Unchecked Exception

There are some Exceptions that occurs at Runtime. These types of Exceptions are ignored by the Compiler.

A common Unchecked Exception is 'ArrayIndexOutOfBoundsException'. Which occurs when you are trying to access a location of an array which doesn't actually exist.

Let us look at the below example :


Main Class

class Main{

   public static void main(String[] arg) {

     String name[] = {"John", "Tom", "Sean"};
     System.out.println(name[5]);

     System.out.println("After the Exception");
   }
}

Output :


Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
   at mainpackage.Main.main(Main.java:6)

So, in the above example, we are trying to access the 6th location of the array. Which doesn't actually exist. And thus we are getting the above Exception.

But there is also a line


System.out.println("After the Exception");

Which doesn't gets printed. In other words the application got halted with this Exception.


The Fix using try - catch block

Main Class

class Main{

   public static void main(String[] arg) {

    try {
     // returns the Class object for the class with the specified name
     String name[] = {"John", "Tom", "Sean"};
     System.out.println(name[5]);

    } catch(ArrayIndexOutOfBoundsException ex) {
     System.out.println(ex.toString());
    }
     System.out.println("After the Exception");
   }
}

Output :


 java.lang.ArrayIndexOutOfBoundsException: 5
 After the Exception

After using the try - catch block. The Exception got caught in the 'try' block and is thrown to the 'catch' block. And the Exception is printed there.


java.lang.ArrayIndexOutOfBoundsException: 5

And most importantly the programme execution doesn't stops but continues as usual. And as we can see the below line is printed.


After the Exception

Multiple catch blocks

There can be a scenario where a piece of code inside a try block may result in more than one Exception. And that is when we need multiple catch blocks to catch those Exceptions but only one which encounters first.

Let us look at the below example :


Main Class

class Main{

   public static void main(String[] arg) {

    try {
     // returns the Class object for the class with the specified name
     String name[] = {"John", "Tom", "Sean"};
     System.out.println(name[2]);
     int x = 15, y = 0;
     int z = 0;

     z = x/y;
     System.out.println("The value is" +z);

    } catch(ArrayIndexOutOfBoundsException ex) {
     System.out.println(ex.toString());
    } catch (ArithmeticException ae) {
     System.out.println ("Can not divide by Zero"+ae);
    } catch (Exception ee) {
     System.out.println ("Generalized Exception"+ee);
    }


   }
}

Output :

 Sean
 Can not divide by Zerojava.lang.ArithmeticException: / by zero

So, in the above case it is a Divide by Zero Exception. Which is caught in


catch (ArithmeticException ae) {
   System.out.println ("Can not divide by Zero"+ae);
  }

Similarly, if there would be any Exception related to Array Index, it would be caught in


catch(ArrayIndexOutOfBoundsException ex) {
   System.out.println(ex.toString());
  }

Also we have put a general catch block to handle the Exception other than the above,


catch (Exception ee) {
   System.out.println ("Generalized Exception"+ee);
  }

Try - Catch with Finally

The Finally block always runs, no matter if the Exception has occurred or not.


Main Class

class Main{

   public static void main(String[] arg) {

    try {
     // returns the Class object for the class with the specified name
     String name[] = {"John", "Tom", "Sean"};
     System.out.println(name[5]);

    } catch(ArrayIndexOutOfBoundsException ex) {
     System.out.println(ex.toString());
    } finally {
     System.out.println("Inside finally Block");
    }
   }
}

Output :

 java.lang.ArrayIndexOutOfBoundsException: 5
 Inside finally Block

So, as we can see in the above example. The finally block executed


Inside finally Block

No matter if an Exception has occurred or not.


Errors

Errors in java are such conditions which cannot be handled. Common errors are a Memory Leak that causes a OutOfMemoryError.