1 The Problem
Let's start with a simple problem. We want to write a program that asks the user for two numbers, divides the first by the second, and prints the result. Sounds easy, right?
- Ask the user for two numbers
- Divide the first by the second
- Print the result
2 Initial Implementation
Step 1 A Simple Division Program
Let's write the most straightforward version of this program using Scanner for input:
DivisionDemo.javaBut what happens if the user enters 0 as the second number?
3 Fix with an if Statement
Step 2 Guard Against Zero
The fix seems obvious — just check if the second number is zero before dividing:
DivisionDemo.java — with if checkThe program no longer crashes. The user gets a friendly message instead of a cryptic error. For a simple program like this, the if check works perfectly fine.
This works when all the code lives in one place. But real programs are not written this way. Good programming practice says we should modularize our code — separate the logic into methods. Let's see what happens when we do that.
4 Make the Program Modular
Step 3 Extract a quotient Method
In real programs, we don't put everything inside main. Good design says we should separate concerns — the division logic belongs in its own method, and main should handle input and output:
DivisionDemo.java — modular versionNow main handles the user interaction, and quotient handles the math. Each part has a clear responsibility. This is how real programs are structured — methods that do one thing well.
Dilemma What Should quotient Do When b Is Zero?
Now main calls quotient. But what should quotient do when b is zero? We can't just add an if check and print a message — the method must return an int.
quotient methodWe have two obvious choices, and both are bad:
We could return -1 or 0 to indicate an error. But these can be valid division results!
- 0 / 5 = 0 — zero is a perfectly valid result
- -4 / 4 = -1 — negative one is a perfectly valid result
There is no "safe" special value we can use. Any integer we return could be a legitimate answer.
We could call System.exit(1) inside the method. But the method should NOT decide to end the program. That decision belongs to the caller.
What if the caller wants to ask the user for a different number? What if the caller wants to log the error? What if the caller wants to try a default value? The method is taking away all of these choices.
5 The Exception Solution
Step 4 Throw an Exception
Instead of returning a bad value or killing the program, we can throw an exception to notify the caller that something went wrong.
quotient method — with exceptionNotice we split this into two lines: first we CREATE the exception object, then we THROW it. This can be done in one line (throw new ArithmeticException(...)), but we split it to help you understand that an exception is just an object — an instance of a class, created with new, like any other object in Java.
Here is what happens visually:
1. Creates the object:
2. throw ex;
3. Catches the same object:
If something is thrown, someone must catch it. This is why try-catch exists.
DivisionDemo.java — with exception handlingIf b is zero, the method throws an exception. The caller catches it and prints a friendly error message. The program does not crash. The caller remains in control and can decide what to do next — ask for new input, use a default, or anything else.
6 Summary
- An exception is an OBJECT that represents an error
- Use throw to send it to the caller
- The caller handles it with try-catch
- This separates business logic from error handling
- The called method reports the problem; the caller decides what to do
In the next lesson, we will study the Exception Class Hierarchy — understanding the family tree of all exceptions in Java.