Exception handling is a mechanism in Java to handle runtime errors, ensuring normal application flow.
1. Exception Hierarchy in Java
The Throwable class is the root of Java’s exception hierarchy.
Throwable
├── Exception
│ ├── IOException
│ ├── SQLException
│ ├── RuntimeException
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ ├── ArithmeticException
├── Error
├── StackOverflowError
├── OutOfMemoryError
- Checked Exceptions: Must be declared in the
throwsclause or handled usingtry-catch. Examples:IOException,SQLException. - Unchecked Exceptions: Subclasses of
RuntimeExceptionand do not require explicit handling. Examples:NullPointerException,ArithmeticException. - Errors: Represent serious problems that applications should not catch. Examples:
OutOfMemoryError,StackOverflowError.
2. Exception vs. Error
| Feature | Exception | Error |
|---|---|---|
| Definition | Recoverable conditions in the program. | Critical issues not meant to be handled. |
| Hierarchy | Subclass of Throwable. | Subclass of Throwable. |
| Examples | IOException, SQLException. | StackOverflowError, OutOfMemoryError. |
| Handling | Can be handled with try-catch. | Should not be handled in most cases. |
3. Can We Write try Without catch and finally?
- Yes, but it must include a
trywith afinallyblock. - Example:
try {
System.out.println("Try block");
} finally {
System.out.println("Finally block");
}
4. Can We Add Statements Between try, catch, and finally?
- No, statements cannot be placed between
try,catch, andfinallyblocks. - Invalid Example:
try {
// Code
}
System.out.println("Invalid"); // Compilation error
catch (Exception e) {
// Code
}
5. Does the Code After try Execute If an Exception Occurs?
- No, if an exception occurs in the
tryblock, the remaining code in thetryblock does not execute. - Example:
try {
System.out.println("Before exception");
int result = 10 / 0; // Exception occurs here
System.out.println("After exception"); // Skipped
} catch (ArithmeticException e) {
System.out.println("Exception caught");
}
6. throw vs. throws
| Feature | throw | throws |
|---|---|---|
| Purpose | Used to explicitly throw an exception. | Declares exceptions a method might throw. |
| Position | Used inside a method. | Declared in the method signature. |
| Syntax | throw new Exception(); | void method() throws Exception {} |
Example of throw
void validateAge(int age) {
if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or above.");
}
}
Example of throws
void readFile() throws IOException {
FileReader fr = new FileReader("file.txt");
}
7. What Happens If an Exception is Thrown by main?
- If an exception is thrown and not handled in
main, it propagates to the JVM, which terminates the program and prints the stack trace. - Example:
public static void main(String[] args) {
throw new RuntimeException("Unhandled exception");
}
8. Unreachable Code in Exception Handling
- Definition: Code that cannot be executed due to improper exception handling.
- Example:
try {
System.out.println("Try block");
return;
} catch (Exception e) {
System.out.println("Catch block");
} finally {
System.out.println("Finally block");
}
System.out.println("Unreachable"); // Compilation error
9. Multi-Catch Blocks
- Definition: A single
catchblock can handle multiple exception types (introduced in Java 7). - Example:
try {
int result = 10 / 0;
String s = null;
s.length();
} catch (ArithmeticException | NullPointerException e) {
System.out.println("Exception: " + e.getMessage());
}
- Rules:
- Exception types must not have a parent-child relationship.
10. Custom Exceptions
- Definition: Custom exceptions are user-defined exceptions that extend
ExceptionorRuntimeException. - Use Case: When specific exceptions related to business logic need to be defined.
Example: Custom Exception
class AgeException extends Exception {
public AgeException(String message) {
super(message);
}
}
public class CustomExceptionDemo {
public static void main(String[] args) {
try {
validateAge(15);
} catch (AgeException e) {
System.out.println("Exception: " + e.getMessage());
}
}
static void validateAge(int age) throws AgeException {
if (age < 18) {
throw new AgeException("Age must be at least 18.");
}
}
}
11. Nested Try-Catch Blocks
- Definition: Try-catch blocks can be nested for handling different exceptions in different sections of code.
- Example:
public class NestedTryCatch {
public static void main(String[] args) {
try {
try {
int result = 10 / 0; // ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Inner catch: " + e.getMessage());
}
String str = null;
str.length(); // NullPointerException
} catch (NullPointerException e) {
System.out.println("Outer catch: " + e.getMessage());
}
}
}
12. Chained Exceptions
- Definition: Allows one exception to be associated with another exception.
- Use Case: To provide more context about the root cause of an exception.
- Methods:
getCause(): Retrieves the original exception.initCause(Throwable cause): Associates a cause with an exception.
Example: Chained Exception
public class ChainedExceptionDemo {
public static void main(String[] args) {
try {
throw new ArithmeticException("Division error").initCause(new NullPointerException("Root cause: Null value"));
} catch (ArithmeticException e) {
System.out.println("Exception: " + e.getMessage());
System.out.println("Cause: " + e.getCause());
}
}
}
13. Final Thoughts on Best Practices
- Handle Exceptions at the Right Level:
- Catch exceptions where they can be meaningfully resolved.
- Avoid Catching Generic Exceptions:
- Do not use
catch (Exception e)unless absolutely necessary.
- Do not use
- Log Exceptions:
- Always log exceptions for debugging and tracking purposes.
- Use Finally for Resource Cleanup:
- Use
finallyor try-with-resources to release resources.
- Use
- Avoid Empty Catch Blocks:
- Always handle exceptions properly to avoid masking issues.
Conclusion
Understanding Java’s exception hierarchy and handling mechanisms helps write robust and error-resilient applications. Concepts like custom exceptions, nested try-catch, chained exceptions, and best practices ensure effective management of runtime issues.