In programming, exception handling is the process of dealing with exceptions and thereby preventing undesired program outcomes. An exception is an unexpected condition that disrupts the flow of our program. In Java Exception Handling, we use the keywords Try, Catch, and Finally. Try, Catch, and Finally are highly useful for handling exceptions and keeping the flow while also debugging the program.
What is an Exception?
Let us begin with an example. Let’s divide two numbers, x, and y. We know that if y is 0, the final value is not defined, therefore this is an exception. An exception in Java is an unexpected condition that can occur during code execution. It is the situation that disrupts the flow of code and causes the program to terminate. Exceptions can cause the program to crash if they are not handled properly. Returning to our previous example, thankfully, by default Java handles this exception with the ArithmeticException class.
How to Handle Exceptions?
Exception Handling is used to deal with exceptions. To manage exceptions, try-and-catch blocks can be used. The try block is used to specify the scope within which an exception can occur. If an exception occurs, the catch block handles it. In the following section, we will learn about the Try Catch block in java.
Try Block in Java
A try block in Java is used to specify a piece of code that may throw an exception. The code within the try block is checked for exceptions, and if an exception is thrown, it is captured by a corresponding catch block. The syntax for a try block in Java is as follows:
Syntax of Try Block in Java:
try
{
// Statements which might contain Exceptions
}
Catch Block in Java
A catch block in Java is used to handle an exception that was thrown within a corresponding try block. The catch block is only executed if an exception is thrown within the try block. A catch block in Java has the following syntax:
Syntax of Catch Block in Java:
catch(Exception e)
{
// Code to handle possible exceptions
}
The catch block defines the type of exception that can be handled. The catch block is invoked when an exception of the specified type is thrown within the corresponding try block.
To handle different types of exceptions, we can have multiple catch blocks following a try block. The order of the catch blocks is critical because the first catch block that matches the type of the thrown exception gets performed. If no matching catch block is detected, the exception is propagated up the call stack to the next available catch block, or to the default exception handler if none is found.
Some Examples of Try Catch Block in Java
Here are some examples of how to use the try catch block in Java:
Example 1 – Handling Arithmetic Exception
try {
int result = 15 / 0; // throws ArithmeticException
} catch (ArithmeticException e) {
System.out.println("An arithmetic exception occurred: " + e.getMessage());
}
Explanation: In this example, we have a try block that contains code that might throw an Arithmetic Exception. The code attempts to divide the integer 15 by 0, which is not allowed and will throw an Arithmetic Exception. The catch block specifies that it can handle this type of exception, and prints an error message to the console that includes the exception message obtained by calling the getMessage() method on the exception object.
Example – 2 Handling NullPointer Exception
try {
String s = null;
System.out.println(s.length()); // NullPointerException
} catch (NullPointerException e) {
System.out.println("A null pointer exception occurred: " + e.getMessage());
}
Explanation: In this example, we have a try block that contains code that might throw a NullPointerException. The code attempts to get the length of a null string, which will throw a NullPointerException. The catch block clearly specifies that it can handle this type of exception, and prints an error message to the console that includes the exception message obtained by calling the getMessage() method on the exception object.
Nested Try Catch Block in Java
We can have a try catch block inside another try catch block in java. This is known as a "nested try catch block". The purpose of using nested try catch block is to handle exceptions in a more specific way.
Syntax of Nested Try Catch Block in Java
try {
// code that may throw an exception
try {
// code that may throw an exception
} catch (Exception e) {
// code to handle the exception
}
} catch (Exception e) {
// code to handle the exception
}
In this syntax, we have an outer try block that contains an inner try block. The code inside the inner try block may possibly throw an exception, which is caught by the catch block inside the inner try block. If the inner try block does not catch the exception, it is propagated up to the catch block inside the outer try block.
The catch block inside the outer try block catches the exception if it is not caught by the inner catch block. This catch block handles the exception and provides appropriate error messages or corrective actions.
One important thing to note is that we can have multiple catch blocks for a single try block, and we can also have multiple nested try-catch blocks in a Java program. The goal of using nested try-catch blocks is to handle exceptions in a more specific and controlled way.
Example of Nested Try Catch in Java
Here’s an example of a nested try catch block in Java:
class PrepBytes{ public static void main(String[] args) { try { try { int[] arr = new int[5]; arr[7] = 10; // This will throw an ArrayIndexOutOfBoundsException } catch (ArrayIndexOutOfBoundsException e) { System.out.println("An array index out of bounds exception occurred: " + e.getMessage()); } int a = 10 / 0; // This will throw an ArithmeticException } catch (ArithmeticException e) { System.out.println("An arithmetic exception occurred: " + e.getMessage()); } } }
Output:
An array index out of bounds exception occurred: Index 7 out of bounds for length 5
An arithmetic exception occurred: / by zero
Finally Block in Java
The finally block in Java is used to define a block of code that will be executed regardless of whether an exception is thrown or not. The finally block is optional, but it is often used in combination with a try-catch block to ensure that certain code is always executed, even if an exception is thrown.
Syntax of Finally Block in Java
try {
// code that might throw an exception
} catch (ExceptionType1 e) {
// handle ExceptionType1
} catch (ExceptionType2 e) {
// handle ExceptionType2
} finally {
// code that is always executed, regardless of whether an exception is thrown or not
}
In the above syntax, we can see that the finally block is placed after all the catch blocks. The code in the finally block will always be executed, whether or not an exception is thrown, and whether or not the catch block(s) execute.
Some important points to keep in mind about the finally block:
- The finally block is always executed, even if there is no matching catch block.
- If an exception is thrown and caught, the finally block is executed after the catch block.
- If there is a return statement in the try or catch block, the finally block is still executed before the method returns.
- If there is an unhandled exception in the try block, the finally block is still executed before the program terminates.
The finally block is typically used to close resources such as files or database connections that were opened in the try block. By doing so, we can ensure that these resources are always properly closed, regardless of whether an exception is thrown or not.
Example of Finally Block in Java
Here’s an example of how to use the finally block in Java:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
class PrepBytes{
public static void main(String[] args) {
Scanner scanner = null;
try {
scanner = new Scanner(new File("input.txt"));
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
System.out.println("File not found");
} finally {
if (scanner != null) {
scanner.close();
}
System.out.println("Program completed");
}
}
}
In this example, we’re reading lines from a file named input.txt. We use a try-catch block to handle the case where the file isn’t found. In the finally block, we close the Scanner object whether or not an exception is thrown. We also print a message indicating that the program has completed. This ensures that the Scanner object is properly closed and any resources it was using are released, even if an exception is thrown.
Summary
Here’s a summary of the key points covered in this conversation:
- Exceptions are errors or unexpected events that occur during program execution.
- We can use try catch block in Java to handle exceptions and prevent our programs from crashing.
- The try block contains the code that might throw an exception, and the catch block contains the code that handles the exception.
- When an exception is thrown, the JVM looks for the nearest catch block that can handle the exception. If it finds one, it executes the catch block and then continues executing the program. If it doesn’t find a catch block, the program crashes.
- We can use multiple catch blocks to handle different types of exceptions. The catch block that is executed depends on the type of exception that was thrown.
- We can use nested try-catch blocks to handle exceptions in a more specific and controlled way. Inner try-catch blocks catch exceptions that are specific to a particular section of code, and outer try-catch blocks catch exceptions that are more general.
- The syntax of a nested try-catch block in Java involves an outer try block that contains an inner try block. The code inside the inner try block may throw an exception, which is caught by the catch block inside the inner try block. If the inner try block does not catch the exception, it is propagated up to the catch block inside the outer try block.
- We can use a finally block to specify code that is executed whether or not an exception is thrown. This is useful for cleaning up resources or releasing locks.
- When an exception is caught in a catch block, we can rethrow the exception by using the throw keyword. This allows us to propagate the exception up to a higher level in the program.
FAQs Related to Try Catch Finally in Java
Here are some frequently asked questions about try-catch-finally blocks in Java:
Q1: Can we have a try block without a catch block in Java?
A: Yes, we can have a try block without a catch block in Java. However, we must include either a catch block or a finally block. If we don’t include a catch block, we must include a finally block.
Q2: Can we have a finally block without a try block in Java?
A: No, we cannot have a finally block without a try block in Java. The finally block is always associated with a try block and contains code that is executed whether or not an exception is thrown in the try block.
Q3: What is the purpose of the finally block in a try-catch-finally block?
A: The finally block contains code that is executed whether or not an exception is thrown in the try block. This is useful for cleaning up resources or releasing locks, which is important to prevent memory leaks or other issues.
Q4: When is the code in the finally block executed?
A: The code in the finally block is always executed, regardless of whether an exception is thrown or not. This ensures that any resources that were opened or locked in the try block are properly cleaned up or released.
Q5: What happens if an exception is thrown inside the finally block?
A: If an exception is thrown inside the finally block, it replaces any exception that was thrown in the try or catch block. This means that the exception that was thrown in the try or catch block is lost and only the exception thrown in the finally block is propagated up the call stack.
Q6: Can we have multiple catch blocks for the same exception in Java?
A: No, we cannot have multiple catch blocks for the same exception in Java. However, we can catch multiple types of exceptions in the same catch block by separating them with a vertical bar (|).