Exception Handling
Exception Handling
Exception Handling
All exception classes are subtypes of the java.lang.Exception class. The exception class is a
subclass of the Throwable class. Other than the exception class there is another subclass
called Error which is derived from the Throwable class.
Errors are abnormal conditions that happen in case of severe failures, these are not handled
by the Java programs. Errors are generated to indicate errors generated by the runtime
environment. Example: JVM is out of memory. Normally, programs cannot recover from
errors.
The Exception class has two main subclasses: IOException class and RuntimeException
Class.
How does a Programmer Handles an Exception?
Customized exception handling in java is achieved using five keywords: try, catch, throw,
throws, and finally. Here is how these keywords work in short.
• Try block contains the program statements that may raise an exception.
• Catch block catches the raised exception and handles it.
• Throw keyword is used to explicitly throw an exception.
• Throws keyword is used to declare an exception.
• Finally block contains statements that must be executed after the try block.
Try-catch block
1. try block
• try block is used to execute doubtful statements which can throw exceptions.
• try block can have multiple statements.
• Try block cannot be executed on itself, there has to be at least one catch block or
finally block with a try block.
• When any exception occurs in a try block, the appropriate exception object will be
redirected to the catch block, this catch block will handle the exception according to
statements in it and continue the further execution.
• The control of execution goes from the try block to the catch block once an exception
occurs.
Syntax
try
{ //Doubtfull Statements.
}
2. catch block
• catch block is used to give a solution or alternative for an exception.
• catch block is used to handle the exception by declaring the type of exception within
the parameter.
• The declared exception must be the parent class exception or the generated exception
type in the exception class hierarchy or a user-defined exception.
• You can use multiple catch blocks with a single try block.
Syntax
try
{
//Doubtful Statements
}
catch(Exception e)
{
}
Example :
public class Main {
public static void main(String[ ] args) {
try {
int[] myNumbers = {10, 1, 2, 3, 5, 11};
System.out.println(myNumbers[10]);
} catch (Exception e) {
System.out.println("Something went wrong.");
}
}
}
2. Multiple Catch Blocks
Java can have a single try block and multiple catch blocks and a relevant catch block gets
executed.
Example 1:
Here we are giving doubtful statements in a try block and using multiple catch blocks to
handle the exception that will occur according to the statement.
public class MultipleCatchBlock1 {
try {
int a[] = new int[5];
a[5] = 30 / 0;
} catch (ArithmeticException e) {
System.out.println("Arithmetic Exception occurs");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBounds Exception occurs");
} catch (Exception e) {
System.out.println("Parent Exception occurs");
}
System.out.println("End of the code");
}
}
Output:
Arithmetic Exception occurs
End of the code
In this example, the try block has doubtful statements that are trying to divide an integer by 0
and 3 catch blocks which have mentioned the exceptions that can handle. After execution of
the try block, the Arithmetic Exception is raised and JVM starts to search for the catch block
to handle the same.
JVM will find the first catch block that can handle the raised exception, and control will be
passed to that catch block. After the exception is handled the flow of the program comes out
from try-catch block and it will execute the rest of the code.
Example 2:
public class MultipleCatchBlock2 {
try {
int a[] = new int[5];
System.out.println(a[10]);
} catch (ArithmeticException e) {
System.out.println("Arithmetic Exception occurs");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBounds Exception occurs");
} catch (Exception e) {
System.out.println("Parent Exception occurs");
}
System.out.println("rest of the code");
}
}
Output:
ArrayIndexOutOfBounds Exception occurs
rest of the code
In this example, try block has doubtful statements that are trying to access elements that are
not present in an array and 3 catch blocks that have mentioned the exceptions that can handle.
After execution of try block, ArrayIndexOutOfBounds Exception is raised and JVM starts to
search for the catch block to handle the same.
JVM will find the second catch block that can handle the raised exception, and control will be
passed to that catch block. After the exception is handled the flow of the program comes out
from try-catch block and it will execute rest of the code.
3. Nested Try Catch
Here we have deep (two-level) nesting which means we have a try-catch block inside a
nested try block. To make you understand better I have given the names to each try block in
comments like try-block2, try-block3, etc.
class NestingDemo {
public static void main(String args[]) {
//main try-block
try {
//try-block2
try {
//try-block3
try {
int arr[] = {
1,
2,
3,
4
};
/* I'm trying to display the value of
* an element which doesn't exist. The
* code should throw an exception
*/
System.out.println(arr[10]);
} catch (ArithmeticException e) {
System.out.print("Arithmetic Exception");
System.out.println(" handled in try-block3");
}
} catch (ArithmeticException e) {
System.out.print("Arithmetic Exception");
System.out.println(" handled in try-block2");
}
} catch (ArithmeticException e3) {
System.out.print("Arithmetic Exception");
System.out.println(" handled in main try-block");
} catch (ArrayIndexOutOfBoundsException e4) {
System.out.print("ArrayIndexOutOfBoundsException");
System.out.println(" handled in main try-block");
} catch (Exception e5) {
System.out.print("Exception");
System.out.println(" handled in main try-block");
}
}
}
Output:
ArrayIndexOutOfBoundsException handled in main try-block
As you can see that the ArrayIndexOutOfBoundsException occurred in the grandchild try-
block3. Since try-block3 is not handling this exception, the control then gets transferred to the
parent try-block2 and looked for the catch handlers in try-block2.
Since the try-block2 is also not handling that exception, the control gets transferred to the
main (grandparent) try-block where it found the appropriate catch block for an exception. We
can use the finally block after the main try-catch block if required.
4. finally block
• finally block is associated with a try, catch block.
• It is executed every time irrespective of exception is thrown or not.
• finally block is used to execute important statements such as closing statement,
release the resources, and release memory also.
• finally block can be used with try block with or without catch block.
Syntax
try
{
//Doubtful Statements
}
catch(Exception e)
{
}
finally
{
//Close resources
}
Example:
public class Main {
public static void main(String[] args) {
try {
int data = 100/0;
System.out.println(data);
} catch (Exception e) {
System.out.println("Can't divide integer by 0!");
} finally {
System.out.println("The 'try catch' is finished.");
}
}
}
Output:
Can't divide integer by 0!
The 'try catch' is finished.
Here, after the execution of try and catch blocks, finally block gets executed. finally block
gets executed even if the catch block is not executed.
6. throw keyword
• throw keyword in java is used to throw an exception explicitly.
• We can throw checked as well as unchecked exceptions (compile-time and runtime)
using it.
• We specify the class of exception object which is to be thrown. The exception has
some error message with it that provides the error description.
• We can also define our own set of conditions for which we can throw an exception
explicitly using the throw keyword.
• The flow of execution of the program stops immediately after the throw statement is
executed and the nearest try block is checked to see if it has a catch statement that
matches the type of exception.
• It tries to find all the catch blocks until it finds the respective handler, else it transfers
the control to the default handler which will halt the program.
Syntax
throw new exception_class("error message");
Example: Here is an example to check the age of the user and raise an exception explicitly
using the throw keyword, if the user doesn't fit in the criteria. Also, a customized message is
given to the user which helps in understanding the exception.
public class Main {
static void checkAge(int age) {
if (age < 18) {
throw new ArithmeticException("Access denied - You must be at least 18 years old.");
} else {
System.out.println("Access granted - You are old enough!");
}
}