Exception Handling in Java
On Day 15, we’ll dive into one of the most crucial concepts in Java: Exception Handling. Exception handling is an essential mechanism in Java that helps developers manage runtime errors and maintain the normal flow of an application. Without proper exception handling, an application can crash or behave unexpectedly.
This article will cover the basics of exceptions, the types of exceptions in Java, and how to handle them effectively using try
, catch
, throw
, throws
, and finally
constructs.
1. What is an Exception?
In Java, an exception is an event that disrupts the normal flow of a program. Exceptions are objects that represent errors or unexpected behavior during program execution.
Exceptions can occur due to various reasons, such as:
Dividing by zero.
Accessing an array with an invalid index.
Trying to open a file that doesn’t exist.
Example:
int a = 10;
int b = 0;
int result = a / b; // This will cause an ArithmeticException
In the above code, dividing by zero causes an ArithmeticException
, terminating the program if not handled properly.
2. Exception Hierarchy in Java
Java exceptions are categorized into a hierarchy that all derive from the base class java.lang.Throwable
. There are two main branches of this hierarchy:
Checked Exceptions (Compile-time Exceptions): These exceptions are checked at compile-time, and the programmer is required to handle them using a
try-catch
block or declare them usingthrows
.- Example:
IOException
,SQLException
,ClassNotFoundException
.
- Example:
Unchecked Exceptions (Runtime Exceptions): These exceptions are not checked during compilation but occur at runtime. They usually occur due to programming mistakes.
- Example:
ArithmeticException
,NullPointerException
,ArrayIndexOutOfBoundsException
.
- Example:
Exception Hierarchy Diagram:
Throwable
|
+-- Exception (Checked)
| +-- IOException
| +-- SQLException
|
+-- RuntimeException (Unchecked)
+-- NullPointerException
+-- ArithmeticException
+-- ArrayIndexOutOfBoundsException
3. Handling Exceptions in Java
Java provides a powerful mechanism to handle exceptions using five main keywords:
try
: The code that might throw an exception is placed inside atry
block.catch
: This block catches and handles the exception.finally
: A block that always executes after thetry-catch
block, whether an exception is thrown or not.throw
: Used to explicitly throw an exception.throws
: Declares that a method can throw exceptions.
Example of try-catch
:
public class Main {
public static void main(String[] args) {
try {
int a = 10;
int b = 0;
int result = a / b; // This line throws an ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
}
}
}
Output:
Cannot divide by zero!
In this example, the ArithmeticException
is caught and handled, preventing the program from terminating abnormally.
4. Types of Exceptions
A. Checked Exceptions
These exceptions are checked by the compiler, and the programmer must handle them using try-catch
or declare them using the throws
keyword.
Example: Handling a Checked Exception (IOException):
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
File file = new File("nonexistentfile.txt");
FileReader fr = new FileReader(file); // This throws FileNotFoundException
} catch (IOException e) {
System.out.println("File not found!");
}
}
}
Output:
File not found!
B. Unchecked Exceptions (Runtime Exceptions)
These exceptions are not checked at compile-time. They occur during runtime due to logical errors in the program.
Example: Handling a Runtime Exception (NullPointerException):
public class Main {
public static void main(String[] args) {
String str = null;
try {
System.out.println(str.length()); // This throws NullPointerException
} catch (NullPointerException e) {
System.out.println("Null value encountered!");
}
}
}
Output:
Null value encountered!
5. throw
and throws
Keywords
A. throw
Keyword:
The throw
keyword is used to explicitly throw an exception. It can be used to throw both checked and unchecked exceptions.
Example: Using throw
to throw an exception:
public class Main {
public static void main(String[] args) {
int age = 15;
if (age < 18) {
throw new ArithmeticException("Age must be at least 18 to vote");
}
}
}
Output:
Exception in thread "main" java.lang.ArithmeticException: Age must be at least 18 to vote
B. throws
Keyword:
The throws
keyword is used to declare exceptions that a method can throw. It tells the caller of the method that it might throw certain exceptions.
Example: Using throws
in Method Declaration:
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
checkFile();
}
public static void checkFile() throws IOException {
throw new IOException("File not found!");
}
}
6. finally
Block
The finally
block is used to execute code regardless of whether an exception was thrown or caught. This is typically used for resource cleanup, such as closing files or database connections.
Example of finally
:
public class Main {
public static void main(String[] args) {
try {
int a = 10;
int b = 0;
int result = a / b;
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
} finally {
System.out.println("Finally block executed.");
}
}
}
Output:
Cannot divide by zero!
Finally block executed.
- In this example, the
finally
block is executed whether or not the exception is caught.
7. Custom Exceptions
In Java, you can create your own custom exceptions by extending the Exception
class (for checked exceptions) or RuntimeException
class (for unchecked exceptions). This is useful when you want to represent specific application-level errors.
Example: Creating a Custom Exception:
class AgeException extends Exception {
public AgeException(String message) {
super(message);
}
}
public class Main {
public static void main(String[] args) {
try {
validateAge(15);
} catch (AgeException e) {
System.out.println(e.getMessage());
}
}
public static void validateAge(int age) throws AgeException {
if (age < 18) {
throw new AgeException("Age must be at least 18 to vote");
}
}
}
Output:
Age must be at least 18 to vote
8. Best Practices for Exception Handling
Use Specific Exceptions: Always catch specific exceptions rather than using a general
Exception
catch block. This improves code readability and debugging.Avoid Silent Catch Blocks: Do not leave catch blocks empty. If an exception occurs, handle it appropriately, log it, or throw it again.
Clean up Resources in
finally
: Always close resources (e.g., file streams, database connections) in thefinally
block to prevent resource leaks.Don’t Use Exceptions for Control Flow: Exceptions should be used to handle errors, not for regular control flow in the program.
9. Summary
By the end of Day 15, we will have a solid understanding of:
What exceptions are and why they are important in Java.
The types of exceptions (checked and unchecked) and how to handle them using
try-catch
.How to use the
throw
andthrows
keywords to handle exceptions effectively.The purpose and use of the
finally
block to ensure resource cleanup.How to create custom exceptions to represent application-specific errors.
Best practices for clean, maintainable exception handling in Java applications.
Exception handling is crucial for building robust Java applications that can recover gracefully from runtime errors. Stay tuned! for further topics on Java.
Subscribe to my newsletter
Read articles from Mohit Upadhyay directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by