Exceptions are unexpected conditions that can occur while a program is running and affect its normal execution. Exception handling provides a way to detect these conditions and execute appropriate code instead of allowing the program to terminate unexpectedly.
- Java mainly categorizes exceptions into checked and unchecked exceptions.
- The try and catch blocks are commonly used to detect and handle exceptions.
Example: Program to use of try-catch block to handle an ArithmeticException that occurs when dividing a number by zero.
public class GFG {
public static void main(String[] args) {
try {
int result = 10 / 0;
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero.");
}
}
}
Output
Cannot divide by zero.
Explanation: The code that may cause an exception is placed inside the try block. When division by zero causes an ArithmeticException, the catch block handles it and prints a message instead of terminating the program.
Types of Exceptions in Java
Java exceptions are broadly classified into checked exceptions and unchecked exceptions based on how they are handled by the compiler.
1. Checked Exceptions
Checked exceptions are checked by the Java compiler during compilation. If a method can produce a checked exception, the exception must be handled using try-catch or declared with throws.Some common checked exceptions are IOException, FileNotFoundException, and ClassNotFoundException.
import java.io.FileReader;
import java.io.IOException;
class FileDemo {
public static void main(String[] args) {
try {
FileReader file = new FileReader("notes.txt");
System.out.println("File opened successfully");
file.close();
}
catch (IOException e) {
System.out.println("Unable to open the file");
}
}
}
Output
Unable to open the file
Explanation: The FileReader attempts to open notes.txt. If the file cannot be found or another input/output problem occurs, an IOException is generated. The catch block handles the exception and displays Unable to open the file.
2. Unchecked Exceptions
Unchecked exceptions are not checked by the compiler during compilation. They generally occur at runtime when the program performs an invalid operation. Common examples include ArithmeticException, NullPointerException, NumberFormatException, and ArrayIndexOutOfBoundsException.
class NumberDemo {
public static void main(String[] args) {
String value = "25A";
try {
int number = Integer.parseInt(value);
System.out.println("Number = " + number);
}
catch (NumberFormatException e) {
System.out.println(
"The value cannot be converted to an integer");
}
}
}
Output
The value cannot be converted to an integer
Explanation: The Integer.parseInt() method converts a string into an integer. Since "25A" contains a non-numeric character, it cannot be converted into an integer. Therefore, Java throws a NumberFormatException, which is handled by the catch block.
Handling Multiple Exceptions
A program may contain statements that can generate different types of exceptions. Java allows multiple catch blocks to handle different exceptions associated with a single try block.
Syntax:
try {
// Statements that may cause an exception
}
catch (ExceptionType1 e) {
// Handles ExceptionType1
}
catch (ExceptionType2 e) {
// Handles ExceptionType2
}
class MultipleCatchDemo {
public static void main(String[] args) {
String input = null;
try {
System.out.println(input.length());
int number = Integer.parseInt("50A");
System.out.println(number);
}
catch (NullPointerException e) {
System.out.println("String value is null");
}
catch (NumberFormatException e) {
System.out.println("Invalid numeric value");
}
}
}
Output
String value is null
Explanation: The input variable contains null. Calling length() on a null reference causes a NullPointerException. Therefore, the first catch block is executed. The statements following the exception inside the try block are not executed.
Example: Handling ArithmeticException
class DivisionDemo {
public static void main(String[] args) {
int total = 240;
int groups = 0;
try {
int result = total / groups;
System.out.println("Result = " + result);
}
catch (ArithmeticException e) {
System.out.println(
"Division by zero is not allowed");
}
}
}
Output
Division by zero is not allowed
Explanation: The value of groups is 0, so the expression total / groups attempts to divide an integer by zero. Java throws an ArithmeticException, and the catch block handles it by displaying an appropriate message.
Example: StackOverflowError
class RecursionDemo {
static void count(int number) {
// Recursive call without a stopping condition
System.out.println("Count: " + number);
count(number + 1);
}
public static void main(String[] args) {
count(1);
}
}
Output:
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.lang.System$1.encodeASCII(System.java:2165)
at java.base/sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:455)
at java.base/sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:563)
at java.base/java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:597)
at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:280)
at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:267)
at java.base/sun.ni...
Explanation: The count() method repeatedly calls itself without a condition to stop the recursion. Each call requires stack memory. Eventually, the available stack space is exhausted and the JVM throws a StackOverflowError. The exact stack trace can vary depending on the Java version and execution environment.