throw and throws
throw
?In Java, sometimes built-in exceptions are not enough — you may want to check your own conditions and manually signal a problem when something is wrong.
This is where the throw
keyword comes in.
The throw
keyword lets you explicitly create an exception object in your own code, then immediately stop execution and pass control to the nearest catch block (or crash the program if there is none).
When is throw
useful?
To enforce business rules.
For example, you might check if an age is below a limit, a number is negative, or a file format is invalid.
To make your API safer: rather than silently failing, you signal errors clearly.
To catch unexpected input early, before it causes bigger bugs later.
Example: Let’s see a clear throw
in action.
How this works (step by step):
The method checkAge
checks if age
is less than 18.
If it is, throw new IllegalArgumentException(...)
creates a new exception object.
throw
immediately stops the method at that line.
If there is no try-catch
around checkAge()
, the exception travels up the call stack, looking for something to catch it.
If nothing catches it, the program crashes and prints a clear error message.
Key point:
throw
is active: it does not wait for Java to find a problem — you define the error condition yourself.
This makes your programs more robust, because you catch bad data as soon as possible, not after it causes hidden bugs later.
throws
?Where throw
creates an exception, the throws
keyword is about declaring that a method might pass an exception to its caller instead of handling it internally.
Why use throws
?
Some problems are better handled by whoever calls the method, not by the method itself.
For example:
Reading a file: the method doesn’t know how you want to handle a missing file.
Connecting to a database: the method shouldn’t decide what to do if the network is down — you should.
Parsing user input: sometimes you want the caller to choose whether to retry, log, or abort.
In Java, some exceptions must be handled (checked exceptions) or declared with throws
.
This is Java’s way of forcing developers to deal with critical errors.
Example: Here’s a clear example using throws
.
How this works (step by step):
readFile()
tries to open test.txt
.
If the file does not exist or there’s an I/O error, new FileReader(...)
throws an IOException
.
readFile()
does not handle it inside — it declares throws IOException
in its signature.
Whoever calls readFile()
(in this case, main
) must handle the exception with try-catch
.
If main
did not handle it, the compiler would refuse to compile the code.
Key point:
throws
doesn’t handle the exception — it simply says, “This method might throw this type — be prepared!”
This keeps code clean: low-level methods don’t decide how to recover — the higher-level caller does.
Understanding checked and unchecked exceptions is critical for writing safe, predictable Java code.
Checked exceptions:
Must be handled with try-catch or declared with throws.
Represent conditions that are outside your program’s control but are expected to happen sometimes.
Examples: IOException
, SQLException
.
These force the developer to think about error handling up front.
Unchecked exceptions:
Are subclasses of RuntimeException
.
Do not need to be declared or caught.
Represent programming bugs: bad logic, null pointers, wrong casts.
Examples: NullPointerException
, ArrayIndexOutOfBoundsException
, ArithmeticException
.
Unchecked exceptions mean “Fix your code!”, while checked exceptions mean “Be prepared for this real-world problem.”
Where throws
matters:
You use throws
mostly for checked exceptions.
Unchecked exceptions don’t require it — they’re assumed to be fixable by writing better code.