Dataslope logoDataslope

Exception Handling

How Java programs deal with things that go wrong — checked vs unchecked exceptions, try/catch/finally, and try-with-resources

Things go wrong. Files are missing. Network calls time out. Users type the wrong thing. Code passes the wrong argument. A robust program does not pretend otherwise — it has a clear, designed answer to every category of failure. In Java, that answer is exceptions.

What is an exception?

An exception is an object that represents "something went wrong right here." When code encounters a problem it cannot handle locally, it throws an exception. The JVM walks back up the call stack looking for a method that catches that kind of exception. If no one does, the program crashes with a stack trace.

A first example

Code Block
Java 8 (Update 492)

Three keywords:

  • try — wraps code that might fail.
  • catch — handles a specific type of exception.
  • finallyalways runs whether or not an exception was thrown. Used for cleanup (closing files, releasing locks).

The exception family tree

Three branches matter:

  • Error — extremely serious, you generally do not catch these (e.g., OutOfMemoryError, StackOverflowError).
  • Exception (other than RuntimeException) — checked. The compiler forces you to either catch them or declare them with throws.
  • RuntimeExceptionunchecked. The compiler does not force you to handle them.

Checked vs unchecked, intuitively

Checked exceptions represent "expected problems with the outside world" — files missing, networks failing, parsing user input. Java forces you to acknowledge them.

Unchecked exceptions represent "your program has a bug" — null pointers, out-of-bounds indices, divisions by zero, illegal arguments. The compiler can't help you with these (every line could have a bug), so it leaves the choice up to you.

A practical rule:

  • Throw an unchecked exception (often IllegalArgumentException or IllegalStateException) when the caller broke a contract.
  • Throw a checked exception when the failure is normal-but-rare and the caller realistically has to handle it.

Declaring with throws

If a method can throw a checked exception that it does not catch, the method must declare it:

Code Block
Java 8 (Update 492)

Notice the wrapping technique: we catch the JDK's NumberFormatException and rethrow our own, more domain-specific BadInputException. Wrapping helps you avoid leaking internal details up to callers.

try-with-resources

Many resources (files, sockets, database connections) must be closed when you're done with them. The pattern used to look like this:

Resource r = open();
try {
    use(r);
} finally {
    r.close();
}

That works, but the try-with-resources form is shorter and safer:

try (Resource r = open()) {
    use(r);
}        // r.close() is called automatically

Any class that implements AutoCloseable (which all standard file/network/DB classes do) is eligible. We are not using real files in this online runner, but the pattern is identical wherever you encounter resources.

Anti-patterns to avoid

Swallowing exceptions

try {
    risky();
} catch (Exception e) {
    // ignore
}

You have just made a bug invisible. When something goes wrong, nothing tells you. The program limps along producing wrong answers. Never write an empty catch block. At minimum log the exception.

Catching Exception (or Throwable)

A broad catch hides bugs you didn't even know about, like a NullPointerException from a typo. Catch the narrowest type that meaningfully handles the problem.

Using exceptions for control flow

try {
    while (true) processNext();
} catch (NoSuchElementException end) {
    // loop exit
}

Exceptions are expensive and obscure the intent. If something is a normal end of input, use a boolean hasNext() instead.

A worked example

Code Block
Java 8 (Update 492)

Expected output:

parsed 42
bad input: not a number: oops
bad input: input was null
done

The program survives all three cases — including the null — because each problem is recognized, named, and handled.

QuestionSelect one

What is the difference between a checked and an unchecked exception?

Checked exceptions are slower

Unchecked exceptions cannot be caught

Checked exceptions must be either caught or declared in a throws clause; unchecked exceptions (RuntimeException and its subclasses) have no such requirement

Unchecked exceptions are always fatal

QuestionSelect one

Why is an empty catch (Exception e) { } block a problem?

It is slow

The compiler refuses to compile it

It silently swallows every failure, hiding bugs and making the program produce wrong answers without telling anyone

It always throws NullPointerException

QuestionSelect one

When is the finally block executed?

Only when no exception was thrown

Only when an exception was thrown

Always — after the try (and any catch) finishes, whether or not an exception was thrown

Only when the JVM is shutting down

A challenge

Challenge
Java 8 (Update 492)
Safe division

Implement SafeMath.divide(int a, int b) that returns a / b, but throws IllegalArgumentException with message "cannot divide by zero" when b is zero.

Main.java is provided. Expected output (exact):

10/2 = 5
10/0 -> cannot divide by zero
done

Exceptions are how Java programs draw a clean line between "the happy path" and "every way things can go wrong." With them in hand, we can finally talk about the broader engineering practice of debugging.

On this page