Throwing Exceptions in Java
-
Last Updated: October 14, 2024
-
By: javahandson
-
Series
In the previous articles, we learned how to handle exceptions using try, catch, and finally block. In this article, we will move a step further and learn about throwing exceptions in Java using the throw and throws keyword.
Throwing an exception means we are signaling to the JVM that an unusual condition has happened and we cannot continue the normal execution of the program. So here we are manually informing the JVM that an exception has occurred. While throwing an exception we can also provide an exception message which indicates what went wrong. The exception that we throw can be a built-in exception or a custom exception.
Built-in exceptions are the checked and unchecked exceptions that we have learned earlier in one of the previous articles i.e. Introduction to Exception Handling in Java.
For throwing an exception we make use of a throw statement. The syntax of the throw statement in Java is quite easy. we use the throw keyword followed by an instance of an exception (or an exception object).
throw new ExceptionType("Error message");
ExceptionType: This can be any subclass of Throwable (such as Exception or RuntimeException). We create a new instance of this exception class using the new keyword.
Error message: This is an optional custom message that provides more information about the exception.
If we throw a checked exception then we should handle it else we will get a compile-time issue but that is not the case with unchecked exceptions. It is not mandatory to handle the unchecked exceptions as they are programming errors.
Write a program to handle the checked exception using a try-catch block.
package com.javahandson; import java.io.File; import java.io.IOException; public class ThrowStatementExample { public static void main(String[] args) { try { File file = new File("file.txt"); boolean ifFileExist = file.exists(); if (!ifFileExist) { throw new IOException("file.txt does not exist"); } } catch (IOException e) { System.out.println(e.getMessage()); } } } Output:file.txt does not exist
What happens if we don’t add a catch block for the corresponding IOException?
In this case, we will get a compilation issue. Hence we always have to handle the checked exceptions. Please check the example below:
package com.javahandson; import java.io.File; import java.io.IOException; public class ThrowStatementExample { public static void main(String[] args) { try { File file = new File("file.txt"); boolean ifFileExist = file.exists(); if (!ifFileExist) { throw new IOException("file.txt does not exist"); } } finally { System.out.println("Clean up the resources"); } } } Output: Exception in thread "main" java.lang.Error: Unresolved compilation problem: Unhandled exception type IOException at com.javahandson.ThrowStatementExample.main(ThrowStatementExample.java)
Write a program to handle the unchecked exception using a try-catch block.
package com.javahandson; public class ThrowStatementExample { public static void main(String[] args) { try { int a = 10; int b = 0; if (b == 0) { throw new ArithmeticException("Cannot divide a number by zero"); } int result = a / b; System.out.println("Result is : " + result); } catch (ArithmeticException e) { System.out.println(e.getMessage()); } } } Output:Cannot divide a number by zero
What happens if we don’t add a catch block for the corresponding ArithmeticException?
The program will be compiled properly and since it is an unchecked exception it is not necessary to handle it manually. It will be handled by the JVM. Please check the example below:
package com.javahandson; public class ThrowStatementExample { public static void main(String[] args) { int a = 10; int b = 0; if (b == 0) { throw new ArithmeticException("Cannot divide a number by zero"); } int result = a / b; System.out.println("Result is : " + result); } } Output: Exception in thread"main"java.lang.ArithmeticException:Cannot divide a number by zero at com.javahandson.ThrowStatementExample.main(ThrowStatementExample.java:12)
The throws keyword is used in the method signature to indicate that the method can throw an exception. The throws keyword informs the caller of the method that they need to handle the exception or propagate it further. Below is the way to use a throws keyword.
public void validate() throws IOException {
}
The above code tells the Java compiler that the method may throw an exception of type IOException. Since this method throws a checked exception hence it should be handled in its caller method.
If we throw a checked exception then we can handle it using the try-catch block that we have seen earlier. But if we are not using the try-catch block then we can use the throws keyword that will delegate the exception to the caller method. Now the caller method can handle that exception using try catch block or propagate it further.
If no caller method handles the exception then the pointer will reach the main method. The main method can handle the exception or it can use the same throws keyword to delegate the exception to the default exception handler of JVM.
Write a program to handle the checked exception using the try-catch block in the caller method.
package com.javahandson; import java.io.File; import java.io.IOException; public class ThrowsKeywordExample { public static void main(String[] args) { caller(); } static void caller() { try { callee(); } catch (IOException e) { System.out.println(e.getMessage()); } } static void callee() throws IOException { File file = new File("file.txt"); boolean ifFileExist = file.exists(); if (!ifFileExist) { throw new IOException("file.txt does not exist"); } } } Output:file.txt does not exist
Write a program to handle the checked exception using the try-catch block in the main method.
package com.javahandson; import java.io.File; import java.io.IOException; public class ThrowsKeywordExample { public static void main(String[] args) { try { caller(); } catch (IOException e) { System.out.println(e.getMessage()); } } static void caller() throws IOException { callee(); } static void callee() throws IOException { File file = new File("file.txt"); boolean ifFileExist = file.exists(); if (!ifFileExist) { throw new IOException("file.txt does not exist"); } } } Output:file.txt does not exist
What happens if the main method also does not handle the checked exception? In this case, a compilation issue will be raised.
package com.javahandson; import java.io.File; import java.io.IOException; public class ThrowsKeywordExample { public static void main(String[] args) { caller(); } static void caller() throws IOException { callee(); } static void callee() throws IOException { File file = new File("file.txt"); boolean ifFileExist = file.exists(); if (!ifFileExist) { throw new IOException("file.txt does not exist"); } } } Output: Exception in thread "main" java.lang.Error: Unresolved compilation problem: Unhandled exception type IOException at com.javahandson.ThrowsKeywordExample.main(ThrowsKeywordExample.java)
Hence we should handle the checked exception using a try-catch block in the main method or we can use the throws keyword in the method signature of the main method so the JVM Default exception handler will handle the exception.
package com.javahandson; import java.io.File; import java.io.IOException; public class ThrowsKeywordExample { public static void main(String[] args) throws IOException { caller(); } static void caller() throws IOException { callee(); } static void callee() throws IOException { File file = new File("file.txt"); boolean ifFileExist = file.exists(); if (!ifFileExist) { throw new IOException("file.txt does not exist"); } } } Output: Exception in thread"main"java.io.IOException:file.txt does not exist at com.javahandson.ThrowsKeywordExample.callee(ThrowsKeywordExample.java) at com.javahandson.ThrowsKeywordExample.caller(ThrowsKeywordExample.java) at com.javahandson.ThrowsKeywordExample.main(ThrowsKeywordExample.java)
In the above program compilation issue will not be raised and the JVM default exception handler will come into the picture and print the complete stack trace of the exception.
If we throw the unchecked exception then we can handle it using the try-catch block that we have seen earlier. But if we are not using try-catch block then we can use the throws keyword that will delegate the exception to the caller method. Now the caller method can handle that exception using try catch block or propagate it further.
If no caller methods handle the exception then the pointer will reach the main method. The main method can handle the exception or it can use the throws keyword to delegate the exception to the default exception handler of JVM.
Write a program to handle the unchecked exception using the try-catch block in the caller method.
package com.javahandson; import java.io.IOException; public class ThrowsKeywordExample { public static void main(String[] args) { caller(); } static void caller() { try { callee(); } catch (ArithmeticException e) { System.out.println(e.getMessage()); } } static void callee() throws ArithmeticException { int a = 10; int b = 0; if (b == 0) { throw new ArithmeticException("Cannot divide a number by zero"); } } } Output:Cannot divide a number by zero
If we don’t add the throws keyword in the method signature of the callee method still the program works fine.
package com.javahandson; import java.io.IOException; public class ThrowsKeywordExample { public static void main(String[] args) throws IOException { caller(); } static void caller() throws IOException { try { callee(); } catch (ArithmeticException e) { System.out.println(e.getMessage()); } } static void callee() { int a = 10; int b = 0; if (b == 0) { throw new ArithmeticException("Cannot divide a number by zero"); } } } Output:Cannot divide a number by zero
So for unchecked exceptions, it is not necessary to add the throws keyword.
Write a program to handle the unchecked exception using the try-catch block in the main method.
package com.javahandson; import java.io.IOException; public class ThrowsKeywordExample { public static void main(String[] args) { try { caller(); } catch (ArithmeticException e) { System.out.println(e.getMessage()); } } static void caller() { callee(); } static void callee() { int a = 10; int b = 0; if (b == 0) { throw new ArithmeticException("Cannot divide a number by zero"); } } } Output:Cannot divide a number by zero
What happens if main method also does not handle the unchecked exception nor a throws keyword is used?
The program executes properly and the exception will be handled by the JVM Default exception handler.
package com.javahandson; public class ThrowsKeywordExample { public static void main(String[] args) { caller(); } static void caller() { callee(); } static void callee() { int a = 10; int b = 0; if (b == 0) { throw new ArithmeticException("Cannot divide a number by zero"); } } } Output: Exception in thread"main"java.lang.ArithmeticException:Cannot divide a number by zero at com.javahandson.ThrowsKeywordExample.callee(ThrowsKeywordExample.java) at com.javahandson.ThrowsKeywordExample.caller(ThrowsKeywordExample.java) at com.javahandson.ThrowsKeywordExample.main(ThrowsKeywordExample.java)
throw | throws |
It is used to explicitly throw an exception. | It states that a method can throw an exception. |
It is used in the method body. | It is used in the method signature. |
It is used to throw only one exception at a time. | We can declare multiple exceptions at a time in the method signature. |
We can throw a checked or unchecked exception. | We can use checked or unchecked exceptions but it is only relevant for checked exceptions. |
throw new IOException() throw new ArithmeticException() | void method() throws IOException |
So this is all about throwing exceptions in java using the throw and throws keyword. 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.