try, catch and finally, blocks
-
Last Updated: October 9, 2024
-
By: javahandson
-
Series
In this article, we will learn what try, catch and finally, blocks are in Java and how they are used in exception-handling mechanisms with proper examples.
The try, catch and finally are blocks used for the exception handling mechanism. These blocks ensure that the exceptions are handled gracefully so that the application will not crash abruptly.
This is the block where we will put the suspicious code. This is the code that might throw an exception. If the code throws an exception then the program jumps to the corresponding catch block.
try { int result = 10/0; // This is a suspicious code that will throw an arithmetic exception hence we have placed it in try block }
If we are declaring a try block then the corresponding catch or finally block should be present else a compilation issue will be thrown.
This block is used to handle the exception that is raised in the corresponding try block.
Write a program to catch the arithmetic exception.
package com.javahandson; public class CatchBlockExample { public static void main(String[] args) { int result = 0; try { result = 10 / 0; // This is a suspicious code and will throw an arithmetic exception System.out.println("Result is : " + result); } catch (ArithmeticException arithmeticException) { System.err.println("Arithmetic exception is encountered"); } } } Output:Arithmetic exception is encountered
We can have multiple catch blocks for a single try block. When an exception is thrown Java checks the catch block(s) to see if any of the catch blocks can handle the exception that was raised. If a matching catch block is found, the control transfers to it and executes the code inside that catch block.
The order of the catch blocks is very important because they are checked in the same order we defined. The first matching block is executed, and the rest are skipped.
The basic rule of placing multiple catch blocks is the most specific exception should be placed before general exceptions. If we place a general exception first, the specific exceptions will never be reached, leading to a compile-time error. General exceptions like Exception or Throwable should be placed last, as they can catch all exceptions.
package com.javahandson; public class CatchBlockExample { public static void main(String[] args) { int result = 0; try { result = 10 / 0; // This is a suspicious code and will throw an arithmetic exception System.out.println("Result is : " + result); } catch (Exception exception) { System.err.println("Exception is encountered"); } catch (ArithmeticException arithmeticException) { System.err.println("Arithmetic exception is encountered"); } } } Output: Exception in thread "main" java.lang.Error: Unresolved compilation problem: Unreachable catch block for ArithmeticException. It is already handled by the catch block for Exception at com.javahandson.CatchBlockExample.main(CatchBlockExample.java)
The above program will not compile because the ordering of the exceptions is wrong. We have placed the most general exception i.e. Exception class at the top so the program will never be able to reach ArithmeticException hence a compilation issue is raised.
package com.javahandson; public class CatchBlockExample { public static void main(String[] args) { int result = 0; try { result = 10 / 0; // This is a suspicious code and will throw an arithmetic exception System.out.println("Result is : " + result); } catch (ArithmeticException arithmeticException) { System.err.println("Arithmetic exception is encountered"); } catch (Exception exception) { System.err.println("Exception is encountered"); } } } Output:Arithmetic exception is encountered
The above program will compile properly because we have placed a more specific exception over the general exception. So the ordering of exceptions is proper now hence the program is executed properly and the exception is caught.
Post Java 7 we can catch multiple exceptions in a single catch block using a pipe ( | ) symbol. This feature can be used if we have the same exception-handling mechanism for all the exception types defined in the catch block.
package com.javahandson; public class MultipleExceptionsOneCatchBlock { public static void main(String[] args) { String lowerCase = "javahandson"; try { String upperCase = lowerCase.toUpperCase(); System.out.println("Converted to upper case : " + upperCase); lowerCase = null; upperCase = lowerCase.toUpperCase(); // Here a null pointer will be raised char ch = lowerCase.charAt(50); // Here a string out of bound exception will be raised System.out.println("Char at 50th position : " + ch); } catch (NullPointerException | StringIndexOutOfBoundsException exception) { System.out.println(exception); } } } Output: Converted to upper case : JAVAHANDSON java.lang.NullPointerException
In the above program toUpperCase method will throw an exception and the pointer will reach the catch block. The subsequent statements in the try block will not execute once a null pointer exception is raised.
If we comment out lowerCase = null, then NullPointerException will not be thrown and we will see a StringIndexOutOfBoundsException.
package com.javahandson; public class MultipleExceptionsOneCatchBlock { public static void main(String[] args) { String lowerCase = "javahandson"; try { String upperCase = lowerCase.toUpperCase(); System.out.println("Converted to upper case : " + upperCase); // lowerCase = null; upperCase = lowerCase.toUpperCase(); char ch = lowerCase.charAt(50); // Here a string out of bound exception will be raised System.out.println("Char at 50th position : " + ch); } catch (NullPointerException | StringIndexOutOfBoundsException exception) { System.out.println(exception); } } } Output: Converted to upper case : JAVAHANDSON java.lang.StringIndexOutOfBoundsException: String index out of range: 50
The finally block is also a part of exception handling mechanism. It is a optional block but if we provide this block then it will always execute even if an exception is thrown or if there is a return statement in the try or catch blocks.
This block is used for cleanup operations and resource management. Suppose we have opened a resource and started some operation but while performing the operation an exception is raised then it might happen that we will not close that resource in the catch block or it can happen that their is no corresponding catch block. So its always recommended to close the resources in the finally block because finally block will always execute even if an exception is raised. The most common use case are:
try { // Code that may throw an exception } catch (ExceptionType e) { // Code to handle exception } finally { // Code that will always execute }
Write a program to check what happens when an exception is raised and a finally block is present.
package com.javahandson; public class FinallyBlockExample { public static void main(String[] args) { try { int result = 10 / 0; } catch (ArithmeticException arithmeticException) { System.err.println("Arithmetic exception is encountered"); } finally { System.out.println("Finally block will be executed"); } } } Output: Arithmetic exception is encountered Finally block will be executed
1. The code inside the finally block will not run if the JVM exits. Ex. System.exit() is use to terminate the currently running Java Virtual Machine (JVM) and end the program immediately.
package com.javahandson; public class FinallyBlockExample { public static void main(String[] args) { int result = getResult(); System.out.println("Result is : " + result); } private static int getResult() { try { int result = 10 / 0; return result; } catch (ArithmeticException arithmeticException) { System.out.println("Arithmetic exception is encountered"); System.exit(0); } finally { System.out.println("Finally block will be executed"); } return 0; } } Output: Arithmetic exception is encountered
In the above program we have a System.exit statement in the catch block that terminates the JVM hence the finally block is not executed nor the result is printed.
2. If there is a return statement in the try or catch block still the finally block will execute before the method returns.
package com.javahandson; public class FinallyBlockExample { public static void main(String[] args) { int result = getResult(); System.out.println("Result is : " + result); } private static int getResult() { try { int result = 10 / 0; return result; } catch (ArithmeticException arithmeticException) { System.out.println("Arithmetic exception is encountered"); return 10; } finally { System.out.println("Finally block will be executed"); } } } Output: Arithmetic exception is encountered Finally block will be executed Result is : 10
In the above program finally block is executed first eventhough a return statement is present in the catch block.
3. The finally block is used for resource cleanup to avoid the resource leaks. Ex. Closing database connections, files etc.
Write a program to read a text file using file input stream and then close the stream.
file.txt Hello, How are you
package com.javahandson; import java.io.FileInputStream; import java.io.IOException; public class FinallyBlockExample { public static void main(String[] args) { FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream("file.txt"); byte[] buffer = new byte[1024]; int bytesRead; // Read bytes from the file into the buffer while ((bytesRead = fileInputStream.read(buffer)) != -1) { // Convert bytes to string and print System.out.println(new String(buffer, 0, bytesRead)); } } catch (IOException e) { System.out.println("File does not exist"); } finally { if (fileInputStream != null) { try { System.out.println("Closing the file input stream"); fileInputStream.close(); // Close the file stream } catch (IOException e) { e.printStackTrace(); } } } } } Output: Hello, How are you Closing the file input stream
In the above program we are reading the file.txt using FileInputStream resource and we are closing that resource in the finally block.
We can write a try block with either of a catch block or finally block. We can skip the catch block if required. The finally block is used to execute code after the try block, regardless of whether an exception is thrown or not.’
Why a catch block is not required?
We may not always want to handle an exception in the try block. In some cases, we might just want the program to throw the exception without catching it locally, but we still need to ensure that the resources are closed. The finally block guarantees this cleanup.
Write a program to clean the resource using try and finally block.
package com.javahandson; import java.io.File; import java.io.FileReader; import java.io.IOException; public class FinallyBlockExample { public static void main(String[] args) throws IOException { FileReader fileReader = null; try { // Opening the file File file = new File("file.txt"); fileReader = new FileReader(file); // Reading and printing the file content int data; while ((data = fileReader.read()) != -1) { System.out.print((char) data); } } finally { // Closing the file reader to free the resource if (fileReader != null) { try { fileReader.close(); System.out.println("\nFile reader closed."); } catch (IOException e) { System.out.println("An error occurred while closing the file reader: " + e.getMessage()); } } } } } Output: Hello, How are you File reader closed.
So this is all about try, catch and finally blocks in java. If you have any questions on this topic, please raise them in the comments section. If you liked this article then please share this post with your friends and colleagues.