throw vs throws in Java
throw and throws in Java look almost identical but do different jobs.
throw actually throws an exception right now. throws warns callers
that a method might throw one. This guide explains both, when Java forces you to use throws, and
how to handle what gets thrown.
First: what is an exception?
An exception is Java's way of saying "something went wrong and I can't carry on normally". Instead of returning a weird value, the method throws an exception object describing the problem. The program then jumps to the nearest code that catches it. If nothing catches it, the program stops and prints the error.
What is the difference between throw and throws?
One is an action; the other is a warning label. Compare them:
throw vs throws
throw
Does it. A statement inside a method body that throws one exception object immediately. Execution stops there and jumps to the nearest matching catch.
- Followed by an object:
throw new X(...) - Throws exactly one exception
- Works with checked and unchecked exceptions
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive");
} throws
Warns about it. Part of a method signature, listing exceptions the method might let escape to its caller.
- Followed by class names:
throws IOException - Can list several, separated by commas
- Required for checked exceptions you don't catch
String readConfig(Path file) throws IOException {
return Files.readString(file);
} throw | throws | |
|---|---|---|
| What it is | A statement | Part of a method declaration |
| Where it goes | Inside a method body | After the method's parameter list |
| Followed by | An exception object (new ...) | Exception class names |
| How many | Exactly one | One or more, comma-separated |
| Purpose | Signal an error now | Tell callers what to expect |
How do you use throw in Java?
Use throw when your code detects a problem it can't fix itself, such as invalid input:
public class Wallet {
private double balance = 50.0;
public void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive, got " + amount);
}
if (amount > balance) {
throw new IllegalStateException("Not enough money: balance is " + balance);
}
balance -= amount; // only runs if no exception was thrown
}
} throw new IllegalArgumentException(...)— creates an exception object withnewand throws it immediately.- Everything after a
throwin that path is skipped, so the balance is never changed by a bad request.
How do you catch a thrown exception?
Wallet wallet = new Wallet();
try {
wallet.withdraw(20);
System.out.println("First withdrawal OK");
wallet.withdraw(100); // throws
System.out.println("This line never runs");
} catch (IllegalStateException e) {
System.out.println("Problem: " + e.getMessage());
}
System.out.println("Program keeps going"); First withdrawal OK Problem: Not enough money: balance is 30.0 Program keeps going
Checked vs unchecked exceptions
Whether you need throws depends on which kind of exception it is:
The exception family tree
- Throwable
- Error serious JVM problems (e.g. OutOfMemoryError). Don't catch.
- Exception CHECKED: must catch or declare with throws
- IOException, SQLException, … checked
- RuntimeException UNCHECKED: throws is optional
- IllegalArgumentException, NullPointerException, IndexOutOfBoundsException, …
Anything under RuntimeException is unchecked. Everything else under Exception is checked, and the compiler won't let you ignore it.
| Checked | Unchecked | |
|---|---|---|
| Extends | Exception (not RuntimeException) | RuntimeException |
| Typical cause | Outside world: missing file, network down | Programming mistake: null, bad index, bad argument |
| Compiler forces handling? | ✔ Yes: catch it or declare throws | ✘ No |
How do you use throws in Java?
Reading a file can fail with an IOException, which is checked. If your method
doesn't catch it, you must declare it with throws. Otherwise the code won't compile:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ConfigLoader {
// ✘ Won't compile: unreported exception IOException; must be caught or declared to be thrown
// static String load(Path file) {
// return Files.readString(file);
// }
// ✔ Option 1: declare it and let the caller decide
static String load(Path file) throws IOException {
return Files.readString(file);
}
// ✔ Option 2: handle it here
static String loadOrDefault(Path file) {
try {
return Files.readString(file);
} catch (IOException e) {
return "defaults";
}
}
public static void main(String[] args) {
System.out.println(loadOrDefault(Path.of("missing.conf")));
try {
load(Path.of("missing.conf"));
} catch (IOException e) {
System.out.println("Caught: " + e.getClass().getSimpleName());
}
}
} defaults Caught: NoSuchFileException
NoSuchFileException is a subclass of IOException, so catch (IOException e) catches it.
Should I catch or declare?
Catch it where you can do something useful, such as use a default, retry, or show a friendly message. If the
current method can't sensibly recover, declare it with throws and let a higher level decide.
Creating your own exception
A custom exception gives callers a precise type to catch:
public class InsufficientFundsException extends RuntimeException {
public InsufficientFundsException(double needed, double available) {
super("Need " + needed + " but only " + available + " available");
}
}
// In Wallet.withdraw(...):
if (amount > balance) {
throw new InsufficientFundsException(amount, balance);
}
Because it extends RuntimeException, it's unchecked and needs no throws. Extend
Exception instead if you want callers to be forced to handle it. The super(...)
call passes the message to the parent class (see the super keyword).
Common mistakes
- Writing
throwsinside a method body orthrowin a signature. They're not interchangeable. - Forgetting
new:throw IllegalArgumentException("x")won't compile; you throw an object. - Catching
Exceptionand doing nothing. An emptycatchhides bugs. At least log the error. - Using exceptions for normal flow, such as ending a loop. They're for unexpected situations.
Quick recap
throwthrows one exception object now;throwsdeclares what a method might throw.- Checked exceptions (like
IOException) must be caught or declared withthrows. - Unchecked exceptions extend
RuntimeExceptionand need nothrows. - Handle exceptions with
try/catchwhere you can actually recover.
What's next?
Next, learn how Java stores groups of objects in the Collections Framework, or browse the full Java keywords list.
Frequently Asked Questions
What is the difference between throw and throws in Java?
throw is a statement that actually throws one exception object right now, like 'throw new IllegalArgumentException()'. throws appears in a method signature and warns callers which checked exceptions the method might throw, like 'void load() throws IOException'.
When do I need to use throws in Java?
When your method can let a checked exception, such as IOException, escape without catching it. The compiler forces you either to catch it with try/catch or to declare it with throws. Unchecked exceptions (RuntimeException and its subclasses) never need throws.
What is the difference between checked and unchecked exceptions?
Checked exceptions represent problems outside your control, such as a missing file or network failure, and the compiler makes you handle or declare them. Unchecked exceptions, subclasses of RuntimeException, usually signal programming mistakes like a null reference or bad argument, and handling them is optional.
Can I throw multiple exceptions at once in Java?
A throw statement throws exactly one exception. But a method can declare several with throws, separated by commas, such as 'throws IOException, SQLException', because different things may go wrong on different runs.
Should my custom exception be checked or unchecked?
Modern Java code usually prefers unchecked exceptions (extend RuntimeException) because they don't clutter every method signature. Use a checked exception (extend Exception) only when callers can realistically recover and you want the compiler to make sure they think about it.