Java Exception Handling

Exception handling in Java is a powerful mechanism that allows developers to detect, handle, and recover from errors at runtime, improving the robustness of applications.


🔹 What is an Exception?

An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions.


🔹 History of Exception Handling in Java

  • Introduced in Java 1.0 with Throwable, Exception, and Error classes.
  • Java’s design emphasized compile-time exception checking.
  • Java 7 introduced try-with-resources for better resource management.
  • Java 14+ added “helpful NullPointerExceptions” for easier debugging.


🔹 Types of Exceptions in Java

1. Checked Exceptions  

    • Handled at compile-time — the compiler requires you to either:
      • Handle them using try-catch, or
      • Declare them using the throws keyword.
    • Typically used for recoverable issues related to external resources (files, DB, network).
    • Examples:
      • IOException — when reading/writing files
      • SQLException — during database operations

2. Unchecked Exceptions    Its programmer's mistake 

    • Handled at runtime — the compiler does not force you to handle them.
    • Caused by programming mistakes, such as missing input validation, unhandled null values, or incorrect logic.
    • It’s the developer’s responsibility to write safe code and perform validations.
    • Examples:
      • NullPointerException — accessing methods on a null object
      • ArithmeticException — divide by zero
      • ArrayIndexOutOfBoundsException — invalid array access
    • These are also called Runtime Exceptions, as they are subclasses of RuntimeException.

3. Errors ⚠️ 

    • Represent serious problems that a Java application should not try to catch or recover from.
    • Typically thrown by the JVM to indicate system-level failures.
    • Examples:
      • OutOfMemoryError — when the JVM runs out of memory
      • StackOverflowError — caused by deep or infinite recursion
      • InternalError — unexpected internal JVM failure
    • Handling Error types is not recommended — they indicate issues beyond the scope of your application.



🔹 Java Exception Hierarchy

java.lang.Object └── java.lang.Throwable     ✅ Base class for all errors and exceptions │── java.lang.Error         ❌ Serious JVM/system errors │ │── AssertionError        ❌ Thrown when an assert fails │ │── LinkageError        ❌ Class linking/loading errors │ │ |── BootstrapMethodError   ❌ Bootstrap resolution failure │ │ |── ClassCircularityError      ❌ Circular inheritance detected │ │ |── ClassFormatError      ❌ Invalid .class file format │ │ |── ExceptionInInitializerError    ❌ Error in static initializer │ │ |── IncompatibleClassChangeError ❌ Binary incompatible class change │ │ |── NoClassDefFoundError ❌ Class missing at runtime │ │ |── UnsupportedClassVersionError ❌ Compiled with newer Java version │ │── ThreadDeath      ❌ Thread killed forcefully │ └── VirtualMachineError     ❌ Critical JVM failure │ |── InternalError        ❌ JVM internal issue │ |── OutOfMemoryError   ❌ JVM out of heap memory │ |── StackOverflowError    ❌ Stack exhausted by recursion │ |── UnknownError      ❌ Unknown serious JVM issue │ └── java.lang.Exception         ✅ Recoverable application-level issues │── java.lang.ClassNotFoundException ✅ Class not found using reflection │── java.lang.CloneNotSupportedException ✅ Clone attempted on non-Cloneable │── java.lang.IllegalAccessException ✅ Illegal access to member/class │── java.lang.InstantiationException    ✅ Instantiating abstract/interface class │── java.lang.InterruptedException ✅ Interrupted thread during block │── java.lang.NoSuchFieldException ✅ Field not found via reflection │── java.lang.NoSuchMethodException ✅ Method not found via reflection │── java.lang.reflect.InvocationTargetException ✅ Thrown by reflective call target │── java.io.IOException          ✅ General I/O failure │ │── EOFException          ✅ End of file unexpectedly reached │ │── FileNotFoundException      ✅ File path not found │ │── InterruptedIOException      ✅ I/O interrupted │ │── ObjectStreamException     ✅ Serialization issues │ │ |── InvalidObjectException      ✅ Invalid serialized object │ │ |── NotActiveException      ✅ Stream not active │ │ |── NotSerializableException     ✅ Object doesn't implement Serializable │ │ |── StreamCorruptedException ✅ Stream format corrupted │ └── UnsupportedEncodingException ✅ Encoding not supported │── java.sql.SQLException        ✅ SQL/database error │ │── SQLClientInfoException      ✅ Client property failure │ │── SQLDataException      ✅ Data conversion issues │ │── SQLFeatureNotSupportedException ✅ Feature unsupported │ │── SQLIntegrityConstraintViolationException ✅ Constraint failure │ │── SQLInvalidAuthorizationSpecException ✅ Bad credentials │ │── SQLNonTransientException   ✅ Non-retryable SQL error │ │── SQLRecoverableException    ✅ Can retry operation │ │── SQLSyntaxErrorException    ✅ Invalid SQL syntax │ └── SQLTimeoutException      ✅ SQL execution timeout └── java.lang.RuntimeException     ❌ Unchecked, logic/bug-related exceptions |── ArithmeticException         ❌ Arithmetic error (e.g., divide by zero) |── ArrayStoreException        ❌ Invalid element type stored in array |── ClassCastException         ❌ Incompatible type casting |── EnumConstantNotPresentException ❌ Missing enum constant |── IllegalArgumentException      ❌ Invalid argument passed | |── NumberFormatException ❌ Number string can't be parsed |── IllegalMonitorStateException      ❌ Monitor method called incorrectly |── IllegalStateException          ❌ Illegal call on current object state |── IndexOutOfBoundsException   ❌ Index is outside bounds | |── ArrayIndexOutOfBoundsException ❌ Invalid array index | |── StringIndexOutOfBoundsException❌ Invalid string index |── NegativeArraySizeException     ❌ Negative size passed to array |── NullPointerException          ❌ Dereferencing a `null` object |── SecurityException           ❌ Security manager violation |── UnsupportedOperationException ❌ Operation not supported |── ConcurrentModificationException ❌ Concurrent modification of collections |── MissingResourceException      ❌ Missing resource in ResourceBundle |── TypeNotPresentException      ❌ Type parameter missing at runtime |── UncheckedIOException      ❌ Unchecked wrapper for IOException |── IllegalThreadStateException      ❌ Illegal thread transition state

🔹 Checked vs Unchecked Exceptions


Feature

Checked Exception

Unchecked Exception

Compile-time check

Yes

No

Base class

Exception (excluding RuntimeException)

RuntimeException and subclasses

When occurs

External events

Logic/programming errors

Handling required?

Yes (must catch or declare)

No (optional)

Examples

IOException, SQLException

NullPointerException, ArithmeticException

Programmer's mistake?

Usually not

Yes — logic bug


🔹 Real-Time Examples of Checked and Unchecked Exceptions


Example : Checked Exception ✅ 
import java.io.*; public class ReadFile { public static void main(String[] args) { try { BufferedReader br = new BufferedReader(new FileReader("data.txt")); String line = br.readLine(); br.close(); } catch (IOException e) { System.out.println("File handling error: " + e.getMessage()); } } }

-Use case: Reading a file
-What can go wrong: File missing, read failure
-Must handle with try-catch or throws

Example  : Unchecked Exception ❌ 
public class DivisionExample { public static void main(String[] args) { int a = 10; int b = 0; int result = a / b; // ArithmeticException System.out.println(result); } }

-Use case: Division
-What can go wrong: Division by zero
-Programmer's mistake — should validate input


🔹 Programmer’s Errors = Unchecked Exceptions


Exception

Example

NullPointerException

Accessing object without null-check

ArrayIndexOutOfBoundsException

Invalid array index

NumberFormatException

Parsing "abc" as Integer

ClassCastException

Invalid cast

IllegalArgumentException

Bad method argument



🔹 Summary – When to use Checked vs Unchecked Exceptions?


Use Case

Type

Reason

Reading file / DB / network

Checked

External resources may fail

Division / parsing input

Unchecked

Code logic issue

Null-checks / indexing

Unchecked

Must be validated by developer


🔹 Basic Example

public class ExceptionExample { public static void main(String[] args) { try { int result = 10 / 0; } catch (ArithmeticException e) { System.out.println("Cannot divide by zero!"); } finally { System.out.println("This block always executes."); } } }


🔹 Multiple Catch Blocks

try { int[] arr = new int[3]; arr[4] = 10; } catch (ArithmeticException e) { System.out.println("Arithmetic error!"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Array index error!"); }


🔹 throw and throws Example

public class ThrowsExample { public static void main(String[] args) throws Exception { checkAge(15); } static void checkAge(int age) throws Exception { if (age < 18) { throw new Exception("Underage - Access Denied"); } else { System.out.println("Access granted"); } } }


🔹 Custom Exception

class MyException extends Exception { public MyException(String message) { super(message); } } public class CustomExceptionExample { public static void main(String[] args) { try { validate(10); } catch (MyException e) { System.out.println("Caught: " + e.getMessage()); } } static void validate(int age) throws MyException { if (age < 18) throw new MyException("Not eligible to vote"); } }


🔹 Real-World Use Cases


Scenario

Exception Type

Description

Reading a file

IOException

File not found/read error

Connecting to a database

SQLException

DB connection failed

Parsing input

NumberFormatException

Invalid format

Division by zero

ArithmeticException

Logic error

Accessing null

NullPointerException

Null object reference

Invalid index

ArrayIndexOutOfBoundsException

Index outside array bounds

Reflection failure

ClassNotFoundException

Class missing at runtime



🔹 Best Practices

  • Catch specific exceptions first
  • Use custom exceptions with meaningful context
  • Always close resources (use try-with-resources or finally)
  • Use logging frameworks (SLF4J, Log4J) instead of printStackTrace
  • Avoid empty catch blocks
  • Don’t catch Throwable, Error, or overly generic Exception


🔹 Common Pitfalls

  • Catching Exception blindly without diagnosing root cause

  • Swallowing exceptions silently

  • Overriding return values in finally block

  • Forgetting to close resources

  • Using empty catch blocks


🔹 Framework-Specific Exception Handling

  • Spring Boot:
    @ControllerAdvice, @ExceptionHandler for global error handling
    Use ResponseEntity for custom REST error responses

  • JDBC / Hibernate / JPA:
    Use DataAccessException, SQL-specific exceptions

  • Servlets / Web Applications:
    Use custom error pages (web.xml), @WebFilter, exception mappers


🔹 Unit Testing Exception Handling (JUnit)

assertThrows(IOException.class, () -> { myService.readFile("missing.txt"); });


🔹 Try-With-Resources (Java 7+)

try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"))) { System.out.println(reader.readLine()); } catch (IOException e) { e.printStackTrace(); }

🔄 Automatically closes resources after use.


🔹 Interfaces in Java Exception Framework


Interface

Description

Serializable

All exceptions implement this for serialization

AutoCloseable

Used with try-with-resources

Closeable

Extended by I/O classes like FileReader


🔹 Quick Summary Table


Category

Examples

Use Cases

Error

OutOfMemoryError, StackOverflowError

Unrecoverable system issues

Checked Exception

IOException, ClassNotFoundException

Recoverable external failures

Unchecked Exception

NullPointerException, IllegalArgumentException

Programmer logic errors