Exception Handling in Java - A Developer’s Lifesaver!
What is Exception Handling?
Exception handling is a mechanism to handle runtime errors gracefully, ensuring the normal flow of the program isn't
interrupted.
It allows us to manage unexpected situations (like division by zero, null references, file not found, etc.) without crashing the
application.
Types of Exceptions in Java
Java exceptions are categorized into two main types:
Checked Exceptions
These are exceptions that are checked at compile time. It means if a method is likely to result in one of these
exceptions and does not handle it, the program will not compile. Checked exceptions must be either caught in a try-
catch block or declared in the method signature using throws. Examples of checked exceptions include IOException
and SQLException.
Checked at compile-time
Must be handled using try-catch or declared with throws
Example: IOException, SQLException
Unchecked Exceptions
These are not checked at compile time, which means the compiler does not require methods to catch or declare these
exceptions. Unchecked exceptions usually indicate programming errors such as logic mistakes (e.g.,
NullPointerException, IndexOutOfBoundsException). They are subclasses of RuntimeException.
Checked at runtime
Usually caused by logical errors or improper use of API
Example: NullPointerException, ArrayIndexOutOfBoundsException
try-catch-finally in Java
What is it?
try-catch-finally is used to handle exceptions gracefully by wrapping the risky code in a try block, handling the exception in
catch, and executing cleanup code in finally.
Syntax:
Key Concepts:
try: Block of code where exceptions might occur.
catch: Handles the specific exception thrown in the try block.
finally: Always executed whether an exception is thrown or not used to close resources like files, DB connections, etc.
Example:
When to use finally?
Closing file streams
Releasing database connections
Unlocking resources
Logging end of operation messages
Sure! Here's the revised version of the throw vs throws explanation with proper examples and their expected outputs inside
the code blocks:
throw vs throws
throw
Used to explicitly throw an exception from a method or any block of code.
It only throws one exception at a time.
throws
Used in method signature to declare exceptions a method might throw.
It passes the responsibility of handling the exception to the caller method.
Summary Table
Keyword Purpose Used in Type
throw To explicitly throw an exception Inside method block Statement
throws To declare possible exceptions In method signature Declaration
Creating Custom Exceptions in Java
Sometimes, predefined exceptions are not enough. In such cases, you can create your own exception by extending the
Exception or RuntimeException class.
Example: Custom Checked Exception
Example: Custom Unchecked Exception
Checked vs Unchecked Exceptions
Checked Exceptions
Definition:
Checked exceptions are the exceptions that are checked at compile-time. These exceptions must be either caught using try-
catch or declared using throws in the method signature.
Examples: IOException, SQLException, FileNotFoundException
Use case: External resources like files, databases, or network connections.
Example: Checked Exception
Unchecked Exceptions
Definition:
Unchecked exceptions are not checked at compile-time, but they occur during runtime. These are usually programming
bugs like logic errors or improper use of APIs.
Examples: NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException
Use case: Typically for programming errors or improper object state.
Example: Unchecked Exception
Summary Table
Feature Checked Exception Unchecked Exception
Checked at Compile-time Runtime
Must handle with try-catch or throws Optional handling
Common examples IOException, SQLException NullPointerException, ArithmeticException
Parent class Exception RuntimeException
Multiple Catch Blocks
In Java, you can use multiple catch blocks to handle different types of exceptions that may occur in a single try block. The
catch blocks are evaluated top to bottom, and the first matching catch block is executed.
Syntax:
Note: Order matters always catch more specific exceptions first, followed by more generic ones like Exception.
Example:
Key Points:
You cannot catch a parent exception before its child (e.g., Exception before ArithmeticException).
Java executes only the first matching catch block.
Great for cleanly handling multiple possible failure points in one block of code.
What is try-with-resources?
Try-with-resources is a Java language feature introduced in Java 7 (so not new to Java 8, but still very important) that makes
managing resources (like files, streams, database connections) easier and safer.
It ensures that resources are automatically closed after use, without needing a separate finally block.
Why use try-with-resources?
In traditional try-catch-finally, you have to close resources manually in the finally block:
This is verbose and error prone (you might forget to close, or cause resource leaks).
How try-with-resources works
Instead, with try-with-resources, you declare the resource inside the parentheses of the try statement:
The resource (br) must implement AutoCloseable interface (which BufferedReader and many other resources do).
The JVM automatically calls br.close() at the end of the try block, even if an exception is thrown.
This eliminates boilerplate and reduces bugs.
Multiple resources
You can also declare multiple resources separated by semicolons:
Key points:
Resources declared in try-with-resources are closed automatically and in reverse order of declaration.
You don’t need to write finally to close resources.
The resource type must implement AutoCloseable (which extends Closeable).
Summary
Feature Traditional try-finally Try-with-resources
Closing resources Manual close in finally Automatic close at block end
Code verbosity Verbose Concise
Exception safety Easy to miss closing, leaks Safer, no leaks
Best Practices in Java Exception Handling
Avoid Empty catch Blocks:
Don't swallow exceptions silently. It hides bugs and makes debugging hard.
Instead you can write:
Always Log Exceptions:
Use a proper logging framework like Log4j, SLF4J, or java.util.logging.
Catch Specific Exceptions First:
Always catch the most specific exceptions before general ones.
Use finally for Cleanup:
Always close resources like streams or DB connections in the finally block or use try-with-resources.
Use Custom Exceptions for Business Logic:
Helps to separate technical vs business errors.
Don’t Use Exceptions for Flow Control:
Avoid writing logic like this
Rethrow Exceptions When Needed:
Don’t suppress important errors pass them on when appropriate.
Some handy Interview Q&A with Examples
1. What is the difference between throw and throws in Java?
Answer:
throw is used to explicitly throw an exception.
throws is used in the method signature to declare exceptions that might be thrown.
Example:
2. What is the difference between Checked and Unchecked exceptions?
Answer:
Checked Exception Unchecked Exception
Checked at compile time Checked at runtime
Must be handled explicitly Optional handling
e.g., IOException, SQLException e.g., NullPointerException, ArithmeticException
Example of Checked Exception:
public void readFile() throws IOException {
FileReader reader = new FileReader("file.txt");
Example of Unchecked Exception:
public void divide(int a, int b) {
int result = a / b; // May throw ArithmeticException if b == 0
3. What is a finally block? When does it not execute?
Answer:
finally block always executes after try-catch, even if an exception is not caught.
Only time it may not execute:
When JVM exits via System.exit(0)
When a fatal error (like segmentation fault or fatal JVM crash) occurs
Example:
4. Can you catch multiple exceptions in one catch block?
Answer:
Yes, from Java 7 onwards using multi-catch (| operator):
5. What is exception propagation?
Answer:
If an exception is not caught in the current method, it propagates to the calling method.
Example:
6. What are custom exceptions?
Answer:
Custom exceptions are user-defined exceptions that extend Exception or RuntimeException.
Example:
7. Can a finally block override a return value from the try or catch block?
Answer:
Yes, if you return in the finally, it overrides other returns, which is a bad practice.
Example:
8. What's the difference between Error and Exception?
Answer:
Error is a serious problem and is not meant to be handled (e.g., OutOfMemoryError)
Exception is meant to be caught and handled in code.
9. What is try-with-resources?
Answer:
Introduced in Java 7, it automatically closes resources like files, sockets, etc.
Example:
10. What is exception chaining in Java?
Answer:
When one exception causes another, we use exception chaining to keep the root cause.
Example:
11. Can a try block exist without a catch?
Answer:
Yes, only if there is a finally block.
12. Is it good to catch Exception or Throwable?
Answer:
No, it’s considered bad practice to catch Throwable or generic Exception, as it may catch unexpected and unrecoverable
errors.
13. Can we create a catch block for multiple exceptions with different handling logic?
Answer:
No, for different logic use separate catch blocks.
14. Can you throw an exception from static block or constructor?
Answer:
Static block: Only unchecked exceptions.
Constructor: Both checked and unchecked, but must be declared using throws.
15. What happens if an exception is not handled?
Answer:
It causes abnormal termination of the program and prints the stack trace.
Final Tip for Interviews, always highlight that:
You follow best practices (never leave empty catch blocks)
You log exceptions with a proper logging framework
You use custom exceptions where appropriate