Unravel › Java concepts › Errors and logging
Exceptions: try, catch, throw
An exception is how Java reports that something went wrong.
At a glance
A fire alarm: when something goes wrong in a room, the alarm travels outward through the building until someone responsible takes charge.
- 1try { ... } catch (IOException e) { ... } finally { ... }: the catch runs if a matching exception occurs in the try; the finally block runs whether or not there was one
- 2Checked exceptions (IOException, SQLException) must be declared with throws or handledUnchecked ones (RuntimeException and subclasses such as NullPointerException, IllegalArgumentException) need no declaration.
- 3Several types can share a handler: catch (IOException | SQLException e)Catch the most specific type first.
- 4throw new IllegalStateException("message", cause) raises onePass the original exception as the cause so its stack trace is not lost.
- An empty catch (or only e.printStackTrace()) swallows the problem: the program carries on in a broken state
- Catching Exception or Throwable broadly also catches things you cannot handle (InterruptedException must restore the interrupt flag, OutOfMemoryError should not be swallowed)
- The JVM keeps an exception table per method: ranges of bytecode with handler addresses
try { int n = Integer.parseInt(input); process(n);} catch (NumberFormatException e) { throw new IllegalArgumentException("not a number: " + input, e);} finally { log.debug("done with {}", input);}Read the full explanation (about 2 min)
An exception is how Java reports that something went wrong. throw raises it, the call stack unwinds until a matching catch handles it, and finally runs either way.
A mental model
A fire alarm: when something goes wrong in a room, the alarm travels outward through the building until someone responsible takes charge. If nobody does, the whole program stops.
How it works
try { ... } catch (IOException e) { ... } finally { ... }: the catch runs if a matching exception occurs in the try; the finally block runs whether or not there was one.
Checked exceptions (IOException, SQLException) must be declared with throws or handled. Unchecked ones (RuntimeException and subclasses such as NullPointerException, IllegalArgumentException) need no declaration.
Several types can share a handler: catch (IOException | SQLException e). Catch the most specific type first.
throw new IllegalStateException("message", cause) raises one. Pass the original exception as the cause so its stack trace is not lost.
Going deeper
An empty catch (or only e.printStackTrace()) swallows the problem: the program carries on in a broken state. At least log it with the exception object, or rethrow.
Catching Exception or Throwable broadly also catches things you cannot handle (InterruptedException must restore the interrupt flag, OutOfMemoryError should not be swallowed).
Do not use exceptions for normal control flow, and do not log and rethrow the same exception at every layer: you get the same trace five times. Handle it once, where you can act.
A return inside finally overrides a thrown exception and hides it.
Under the hood
The JVM keeps an exception table per method: ranges of bytecode with handler addresses. Throwing creates the exception object and fills in the stack trace, which is the expensive part (hence the advice not to use exceptions for flow control).
Common mistakes
- Empty catch blocks.
- Losing the cause when wrapping.
- Catching
Exceptiontoo broadly. - Logging and rethrowing at every layer.
- Ignoring
InterruptedException.
How Unravel recognises it
When you paste code, Unravel looks for these signs of exceptions: try, catch, throw. Spotting them yourself is a good habit when you read unfamiliar code:
- Language constructs:
trycatchthrowfinally
Part of a learning path
- Reliable code · next: try-with-resources
Related concepts
Builds on this
Frequently asked questions
What is Exceptions: try, catch, throw?
An exception is how Java reports that something went wrong. throw raises it, the call stack unwinds until a matching catch handles it, and finally runs either way.
What are the most common mistakes with Exceptions: try, catch, throw?
Empty catch blocks. Losing the cause when wrapping. Catching Exception too broadly. Logging and rethrowing at every layer. Ignoring InterruptedException.
How can I see Exceptions: try, catch, throw in real code?
Paste your own Java into Unravel and it will point out where exceptions: try, catch, throw appears, explain how it works at the detail level you choose, and draw the flow of the code around it.