Exception Handling
## Learning Objectives
- Understand exception types
- Use try, catch, finally
- Throw custom exceptions
- Handle exceptions gracefully
## What is an Exception?
An event that disrupts normal program flow:
```java
public class Main {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
System.out.println(numbers[5]); // ArrayIndexOutOfBoundsException!
}
}
```
## Exception Hierarchy
```text
Throwable
├── Error (system, unrecoverable)
│ ├── OutOfMemoryError
│ └── StackOverflowError
└── Exception (recoverable)
├── RuntimeException (unchecked)
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ └── ArithmeticException
└── Other (checked)
├── IOException
└── SQLException
```
## Try-Catch
### Basic Syntax
```java
try {
int result = 10 / 0; // Might throw
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
}
```
### Multiple Catch
```java
try {
int[] arr = new int[5];
arr[10] = 100;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array index error!");
} catch (ArithmeticException e) {
System.out.println("Math error!");
} catch (Exception e) {
System.out.println("Generic error: " + e.getMessage());
}
```
### Catch Order
Most specific first, then general:
```java
try {
// code
} catch (NullPointerException e) { // Specific first
// handle
} catch (RuntimeException e) { // Then more general
// handle
} catch (Exception e) { // Finally, most general
// handle
}
```
## Finally Block
### Always Executes
```java
Scanner scanner = new Scanner(System.in);
try {
System.out.print("Enter number: ");
int num = Integer.parseInt(scanner.nextLine());
System.out.println("Result: " + 10 / num);
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero");
} finally {
System.out.println("Closing scanner");
scanner.close(); // Always runs!
}
```
### Try-with-resources (Java 7+)
```java
try (Scanner scanner = new Scanner(System.in)) {
int num = Integer.parseInt(scanner.nextLine());
System.out.println("Result: " + 10 / num);
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero");
}
// Scanner automatically closed
```
## Throwing Exceptions
### throw Keyword
```java
public static void validateAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
if (age > 150) {
throw new IllegalArgumentException("Age is too high");
}
}
```
### Exception Types
| Type | When to Throw |
|------|--------------|
| IllegalArgumentException | Invalid argument |
| IllegalStateException | Invalid state |
| NullPointerException | null value where not allowed |
| IndexOutOfBoundsException | Index out of range |
| UnsupportedOperationException | Operation not supported |
## Custom Exceptions
### Define Exception Class
```java
public class ValidationException extends Exception {
public ValidationException(String message) {
super(message);
}
}
public class InvalidEmailException extends ValidationException {
public InvalidEmailException(String email) {
super("Invalid email: " + email);
}
}
```
### Using Custom Exception
```java
public static void registerUser(String email) throws ValidationException {
if (!email.contains("@")) {
throw new InvalidEmailException(email);
}
// registration logic
}
```
## Checked vs Unchecked
### Checked Exceptions
Must handle or declare:
```java
public void readFile() throws IOException {
FileReader reader = new FileReader("file.txt");
// Must handle IOException
reader.close();
}
```
### Unchecked Exceptions
No requirement to handle:
```java
public void accessArray() {
int[] arr = {1, 2, 3};
arr[10] = 5; // RuntimeException - can but don't have to handle
}
```
## Common Exception Types
```java
// NullPointerException
String str = null;
str.length(); // NPE
// ArrayIndexOutOfBoundsException
int[] arr = {1, 2};
arr[5] = 10; // AIOOBE
// ArithmeticException
int x = 10 / 0; // Division by zero
// ClassCastException
Object obj = "hello";
Integer num = (Integer) obj; // CCE
// NumberFormatException
int num = Integer.parseInt("abc"); // NFE
```
## Exception Methods
```java
try {
riskyOperation();
} catch (Exception e) {
e.getMessage(); // Brief description
e.getCause(); // Cause exception
e.printStackTrace(); // Full stack trace
}
```
## Best Practices
### Do
```java
// Catch specific exceptions
try {
FileReader reader = new FileReader("file.txt");
} catch (FileNotFoundException e) {
// Handle specific exception
}
// Clean up resources
try (FileReader reader = new FileReader("file.txt")) {
// use reader
}
// Log and rethrow
try {
doSomething();
} catch (Exception e) {
logger.error("Failed", e);
throw e;
}
```
### Don't
```java
// Don't swallow exceptions
try {
doSomething();
} catch (Exception e) {
// Doing nothing hides bugs!
}
// Don't catch Throwable
try {
doSomething();
} catch (Throwable t) { // Catches everything including Errors!
// Too broad!
}
```
## Summary
- Exceptions disrupt normal flow
- try-catch-finally handles exceptions
- finally always executes (use try-with-resources)
- throw throws an exception; throws declares exception
- Custom exceptions extend Exception
- Checked: must handle; Unchecked: optional
- Catch specific exceptions first
- Never silently swallow exceptions
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →