Exception Classes and the Throwable Hierarchy
A throw statement lets a program deliberately throw an exception when it finds an error it cannot handle where it was discovered.
Try it: try / except / else / finally
How an exception jumps out of a try block to the first matching except clause, when else runs, and why finally always runs.
How it works
- Statements in try run until one raises an exception; the rest of try is skipped.
- Python checks the except clauses in order and runs the first one whose type matches.
- If nothing was raised, the else block runs instead.
- finally runs in every case.
Default run (9 steps): Call safe_divide('4'). … Return 25.0. Output was: Worked: 25.0 / Done.
Simplified: One fixed function; int() and / are modelled exactly (including how Python prints floats), but nothing is executed as Python.
Loading the simulation…
A Helper Method That Cannot Decide
Most of the time, a program that finds an error can deal with it right where the error is found. Imagine instead a helper method that is asked to do arithmetic it cannot complete. The helper has no idea what the caller wants to happen next. Should it print a message and keep going? Should it stop the whole program? The helper may simply not have enough context to decide.
Java offers a way out of this situation. A program can deliberately create an exception and throw it, hoping that some other part of the program will catch it and respond appropriately. The statement that does this is the throw statement. As you read the rest of this article, keep one question in mind: when a throw statement executes, which parts of the program still run, and which parts are skipped?
Where Normal Execution Stops
Ordinary code runs one statement after another. A method call that returns a value sends the program back to the line that made the call, and the expected sequence continues. A throw statement breaks that expectation. Once the throw statement runs, the method stops at that point. There is no return value and no normal continuation of the method body.
int result = divide(10, 2);
System.out.println("Result: " + result);divide returns 5, so the Result line runs normally
int result = divide(10, 0);
System.out.println("Result: " + result);divide throws, so the assignment and the Result line are skipped
The diagram shows the divergence. In the before case, the method returns a value and the Result line runs. In the after case, the throw statement stops the method, the line that would have printed the result never runs, and control jumps to the catch clause in the calling code.
Why Throw Instead of Handle Here
A throw statement lets a program deliberately throw an exception when it finds an error it cannot handle where it was discovered.
The key decision is about context. A helper method that detects a problem may not know whether the problem is fatal, whether it should be retried, or whether the user should see a message. The caller usually knows more. Throwing the exception hands the problem to the code that surrounds the call, which is the part of the program able to decide what should happen next.
A throw statement is therefore a choice to stop processing in the current method and let an outer part of the program respond. It is not a way to hide errors. Handling at the point of discovery remains the right choice when the local code has enough information to recover on its own.
Anatomy of a Throw Statement
A throw statement has a single required part: an exception object. The keyword throw is followed by the object being thrown, and then a semicolon. The general form is therefore throw followed by an exception object and a semicolon.
The exception object is not just any value. It must belong to a subclass of Throwable. In practice it usually belongs to a subclass of Exception, and it is most often a brand-new object created with the new operator. The string passed to the constructor is stored inside the exception object as its error message. Any code that holds a reference to that object can later call getMessage() to read the message, so the catching code does not need to know where the problem was detected.
Tracing Control from Throw to Finally
A thrown exception is processed in exactly the same way whether the system threw it or a throw statement did. The path depends on what surrounds the point where the exception appears. Follow the flowchart from the moment the throw statement runs to the point where the program continues.
Two rules from the source drive this path. First, when a catch clause handles the exception, the computer jumps to that clause and runs it, and the exception is then considered handled. Second, the finally clause runs after the handling, if one exists, and then the program carries on with the statements that follow the try statement. The source does not describe what happens when no catch clause in the try statement handles the exception, so this article does not cover that path.
Running a Division Example
The program below puts the pieces together. A helper method checks for a zero divisor and throws an ArithmeticException when it finds one. The main method calls that helper inside a try statement, with a catch clause and a finally clause. Read the code and mark the lines you expect to run before you look at the output.
Before call
Caught: divisor is zero
Finally runs
After try statement- The throw statement creates a new
ArithmeticExceptionwith a message. - The divide method stops at the throw, so it returns no value and prints nothing itself.
- The Result line is skipped because control jumped out of the try block.
getMessage()returns the string passed to the constructor.
What do you think happens?
Before reading the output, which of the four lines will print, and in what order?
Reveal answer
Before call, then Caught: divisor is zero, then Finally runs, then After try statement. The Result line never prints.
The throw inside divide transfers control to the matching catch clause, skipping the rest of the try block. The finally clause then runs, and execution continues after the try statement.
Notice what the program does not contain: divide does not print anything and does not return a value when the divisor is zero. The decision about what the user sees is made by main, the code around the call, not by the method that detected the problem.
Exceptions the System Throws Itself
The example throws an exception for division by zero, which raises a natural question: does the system ever do this on its own? For integer division it does. If both numbers are of type int, dividing by zero causes the system to throw an ArithmeticException. Floating-point arithmetic behaves differently. No arithmetic operation with floating-point numbers produces an exception. Instead, the special value Double.NaN represents the result of an illegal operation.
Mistakes Beginners Make with Throw
Common mistake Expecting code after the throw statement to run
What it looks likethrow new ArithmeticException("bad"); followed by System.out.println("still here");Why it failsA throw statement transfers control away from the current method, so the statements that follow it in that block are skipped.
Do this insteadPlace only the code that should run when the error occurs before the throw, and move any cleanup into a finally clause.
Common mistake Throwing an object that is not a Throwable
Why it failsThe thrown object must belong to a subclass of Throwable. Usually it is a subclass of Exception.
Do this insteadCreate an Exception-type object with the new operator, such as new ArithmeticException(message).
Common mistake Throwing when the local code could simply handle the problem
Why it failsThrowing sends the problem to a caller. If the current method can recover completely, throwing adds unnecessary control transfer.
Do this insteadHandle the error where it is discovered when the local code has enough context, and throw only when the caller is better placed to decide.
Common mistake Forgetting that the message is stored in the object
Why it failsThe string passed to the constructor is the message. If it is left vague, the catching code has no useful information.
Do this insteadPass a descriptive string such as divisor is zero, and read it later with getMessage().
Practice: Predict the Path
Modify the DivisionDemo program so that divide is called with the arguments 10 and 2 instead of 10 and 0. Before running it, predict which lines print and whether the finally clause still runs. Then explain in one or two sentences why the Result line now appears.
Hints
- Ask whether divide reaches its throw statement when b is 2.
- If no exception is thrown, does control jump to the catch clause?
- The finally clause runs in both cases, because it follows the try statement's handling.
Key Takeaways
- A throw statement lets a program deliberately throw an exception when it finds an error it cannot handle where it was discovered, passing the problem to code that can decide what to do.
- A thrown object must belong to a Throwable subclass, usually an Exception subclass, and is most often created with the new operator; the constructor string becomes the message returned by
getMessage(). - When an exception is thrown, control jumps to a matching catch clause, the finally clause runs, and the program continues after the try statement, skipping any remaining lines of the try block.
- The divergence from expected behavior happens at the throw statement: the method stops there and produces no return value, and the code that surrounds the call decides what happens next.
- The system throws
ArithmeticExceptionon its own for integer division by zero, while floating-point operations produceDouble.NaNrather than an exception.