throw & throws
throw & throws
In the previous lessons you learned how to catch exceptions that the JVM or the standard library raises. Sometimes, though, your own code needs to signal that something has gone wrong. That is what throw and throws are for. These two keywords look similar but serve very different roles — understanding both is essential for writing honest, self-documenting Java.
throw — raising an exception yourself
The throw keyword lets you create and fire an exception object at any point in your code. The moment Java hits a throw statement, execution of the current method stops and the exception starts travelling up the call stack looking for a matching catch block.
Notice a few things:
throwtakes an object — you always writethrow new SomeException("message").- You choose the most specific exception class that fits the problem.
IllegalArgumentExceptionis right for bad inputs;IllegalStateExceptionis right when the object itself is in the wrong state. - The message string should help the caller diagnose the issue — include the bad value where possible.
-1 or null to indicate failure forces every caller to remember to check — and they often forget. An exception cannot be silently ignored: if no one catches it, the program terminates with a visible stack trace.
throws — advertising checked exceptions
The throws keyword belongs on the method signature, not inside the body. It is a contract: it tells the compiler and every caller "this method might throw the listed checked exception, and you must deal with it."
Because IOException is a checked exception, the compiler forces every caller of readFile to either:
- Surround the call in a
try-catchblock, or - Add the same
throws IOExceptiondeclaration to their own method, propagating the responsibility further up.
throws. RuntimeException and its subclasses (like IllegalArgumentException, NullPointerException) can be thrown anywhere without declaring them. Only checked exceptions (those that extend Exception but not RuntimeException) must be declared.
How the stack unwinds — propagation
When an exception is thrown and no matching catch is found in the current method, Java moves to the caller of that method and looks again. This continues up the chain until either a handler is found or the exception reaches the top of the stack (which crashes the thread).
Output:
level3 throws, level2 and level1 do not catch it, and it travels all the way to main where it is finally handled. The call stack unwinds automatically — no extra code needed in level1 or level2.
Combining throw and throws
A method that both declares a checked exception (with throws) and manually raises it (with throw) is very common:
Exception or Throwable directly. Writing throw new Exception("something broke") forces callers to catch the broadest possible type, obscuring what actually went wrong. Always prefer a specific, meaningful exception class — use standard ones from the JDK or create your own (covered in Lesson 7).
A complete worked example
Summary
throwgoes inside a method body — it fires an exception object right now.throwsgoes on the method signature — it declares that the method might throw a checked exception and pushes the handling responsibility onto the caller.- Unchecked exceptions (
RuntimeExceptionsubclasses) can be thrown freely without being declared. - When an exception is not caught locally, it propagates up the call stack automatically until something catches it or the program terminates.