Common Built-in Exceptions in Java Every Developer Encounters

Illustration for Common Built-in Exceptions in Java Every Developer Encounters
By Last updated:

Picture this: you’re driving on a highway. Most of the time the ride is smooth, but occasionally, you may hit a speed bump (exception) or, rarely, face engine failure (error). Java applications behave the same way—smooth execution interrupted by built-in exceptions.

Understanding these common exceptions helps you anticipate problems, debug faster, and write resilient, production-ready applications. This guide explores the most frequently encountered built-in exceptions, complete with real-world analogies and best practices.


Purpose of Java Exception Handling

Exception handling in Java:

  • Prevents crashes and ensures graceful recovery.
  • Separates business logic from error-handling logic.
  • Helps developers track down problems via stack traces.
  • Ensures resources like files or sockets are properly closed.

Real-world analogy: Exception handling is like airbags in a car—you hope you don’t need them, but when an accident occurs, they protect you.


Errors vs Exceptions in Java

At the top of the hierarchy is Throwable, which splits into:

  • Error: Serious issues beyond developer control (e.g., OutOfMemoryError, StackOverflowError).
  • Exception: Recoverable conditions your program can handle (e.g., IOException, NullPointerException).
try {
    int result = 10 / 0; // ArithmeticException
} catch (ArithmeticException e) {
    System.out.println("Cannot divide by zero!");
}

Java Exception Hierarchy Diagram

Throwable
 ├── Error (unrecoverable)
 │    └── OutOfMemoryError, StackOverflowError
 └── Exception
      ├── Checked (must be declared or handled)
      │    └── IOException, SQLException
      └── Unchecked (RuntimeException and subclasses)
           └── NullPointerException, ArithmeticException

Checked vs Unchecked Exceptions

  • Checked exceptions: Must be handled or declared. Example: IOException.
  • Unchecked exceptions: Runtime exceptions not enforced by the compiler. Example: NullPointerException.

Basic Syntax: try, catch, finally

try {
    FileReader fr = new FileReader("file.txt");
} catch (FileNotFoundException e) {
    System.out.println("File not found!");
} finally {
    System.out.println("Cleanup always executes");
}

Common Built-in Exceptions in Java

Let’s break down the exceptions you’ll encounter most often.

1. NullPointerException

Occurs when accessing a method or property on a null object.

String text = null;
System.out.println(text.length()); // NullPointerException

Analogy: Trying to call someone using a phone without a SIM card.


2. ArrayIndexOutOfBoundsException

Accessing an array element outside its valid range.

int[] arr = new int[3];
System.out.println(arr[5]); // ArrayIndexOutOfBoundsException

Analogy: Asking for seat number 50 in a bus with only 30 seats.


3. ArithmeticException

Illegal arithmetic operations like division by zero.

int result = 10 / 0; // ArithmeticException

Analogy: Trying to split a pizza among zero people.


4. ClassCastException

Invalid type casting between incompatible objects.

Object x = "Hello";
Integer y = (Integer) x; // ClassCastException

Analogy: Trying to fit a square peg into a round hole.


5. NumberFormatException

Occurs when parsing an invalid number string.

int num = Integer.parseInt("abc"); // NumberFormatException

Analogy: Trying to convert “apple” into a number.


6. IllegalArgumentException

Thrown when a method receives an inappropriate argument.

Thread t = new Thread();
t.setPriority(15); // IllegalArgumentException (valid range 1–10)

Analogy: Asking someone to run at 200 km/h—it’s not possible.


7. IllegalStateException

Raised when an object is in an inappropriate state.

Stream<String> s = Stream.of("a", "b");
s.count();
s.count(); // IllegalStateException (stream already consumed)

Analogy: Trying to withdraw money from a closed bank account.


8. IOException

General I/O failure such as file not found or read error.

try (FileReader reader = new FileReader("missing.txt")) {
    // ...
} catch (IOException e) {
    e.printStackTrace();
}

Analogy: Trying to open a locked door without the right key.


9. SQLException

Database-related errors such as invalid queries or connection failures.

try (Connection con = DriverManager.getConnection(url, user, pass)) {
    // query
} catch (SQLException e) {
    e.printStackTrace();
}

Analogy: Asking a librarian for a book that doesn’t exist.


10. FileNotFoundException

A subtype of IOException when a file doesn’t exist.

FileReader fr = new FileReader("nonexistent.txt"); // FileNotFoundException

Analogy: Looking for your keys in a place where they never were.


Multiple Catch Blocks Example

try {
    int[] arr = new int[2];
    arr[5] = 10;
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Array index issue!");
} catch (RuntimeException e) {
    System.out.println("Other runtime issue!");
}

Exception Chaining Example

try {
    dbCall();
} catch (SQLException e) {
    throw new RuntimeException("Database error", e);
}

Try-with-Resources Example

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

Logging Exceptions

try {
    risky();
} catch (Exception e) {
    logger.error("Operation failed", e);
}

Best Practices

  • Catch only what you can handle.
  • Place specific exceptions before general ones.
  • Use try-with-resources for cleanup.
  • Avoid empty catch blocks.
  • Provide meaningful exception messages.

Common Anti-Patterns

  • Catching Exception blindly.
  • Using exceptions for control flow.
  • Logging and rethrowing without purpose.
  • Ignoring suppressed exceptions.

Performance Considerations

  • Try-catch itself is cheap.
  • Throwing exceptions is expensive—don’t use for normal control flow.
  • Validate inputs proactively.

📌 What's New in Java Exception Handling

  • Java 7+: Multi-catch, try-with-resources.
  • Java 8: Exceptions in lambdas and streams.
  • Java 9+: Stack-Walking API improvements.
  • Java 14+: Helpful NullPointerException messages.
  • Java 21: Structured concurrency and virtual thread exception handling.

FAQ: Expert-Level Questions

Q1. Why can’t I catch Error?
Errors are unrecoverable (e.g., OutOfMemoryError).

Q2. Which exceptions are most common in beginners’ code?
NullPointerException, ArrayIndexOutOfBoundsException, and ArithmeticException.

Q3. Is catching Exception always bad?
Yes, unless you’re at an application boundary (e.g., global handler).

Q4. Does exception handling affect performance?
Only when exceptions are thrown, not during normal execution.

Q5. Can lambdas throw checked exceptions?
Not directly—use wrappers or custom interfaces.

Q6. Should I log all exceptions?
No, log where it adds value—avoid duplicate logs.

Q7. What’s exception translation?
Wrapping low-level exceptions in domain-specific ones.

Q8. How do async frameworks handle exceptions?
Through futures (ExecutionException) or CompletableFuture.exceptionally().

Q9. How do suppressed exceptions appear?
When multiple exceptions occur in try-with-resources.

Q10. How do reactive frameworks handle exceptions?
Using operators like onErrorResume and onErrorReturn.


Conclusion and Key Takeaways

  • Java provides many built-in exceptions to cover common error cases.
  • Recognizing them early helps in debugging and error recovery.
  • Use specific exception handling, not broad catches.
  • Follow best practices to build resilient, maintainable applications.

By mastering these common exceptions, you’ll write safer, production-ready Java applications.