throw vs throws in Java
throw raises an exception; throws declares it in a signature.
throw and throws — one letter apart. Mix them up and the compiler stops you cold. Do you know which one pulls the alarm and which one just warns?Pull the alarm: throw
**throw is a statement inside a method body. It raises one exception object** right now. Java has no raise keyword — it's always throw plus an object.
void setAge(int age) {
if (age < 0)
throw new IllegalArgumentException("age");
this.age = age;
}Post a warning sign: throws
**throws belongs in the method signature. It tells callers which checked exceptions may escape — and it's required for them. You throw one object, but you can declare several types**: throws IOException, SQLException.
String load(Path p) throws IOException {
return Files.readString(p);
}Leaving the loop
The catch is outside the loop. What prints?
void check(int n) {
if (n > 2) throw new RuntimeException();
System.out.print(n);
}
void main() {
try {
for (int i = 1; i < 6; i++) check(i);
} catch (RuntimeException e) {
System.out.print("!");
}
}12!12!45123!12345
Show the answer
check prints 1 and 2, then throws on 3. The exception leaves check, then the loop, until the catch outside it. So 3, 4 and 5 are never printed.
Swapping the keywords
throws inside a body or throw in a signature are both compile errors. Memory trick: throws has an s because it can list several types in the signature.
void bad() throw IOException { } // error
void bad2() {
throws new RuntimeException(); // error
}Overrides can't add surprises
Code holding a Reader expects read() to throw no checked exceptions. So an override can't declare new or broader checked exceptions — that's a compile error. It may declare fewer or narrower ones.
class Reader {
void read() { }
}
class FastReader extends Reader {
@Override
void read() throws Exception { } // error
}Declaring unchecked ones?
May you write throws IllegalArgumentException on a method?
Think about it, then reveal the answer
Yes — it's allowed but optional. throws is only *required* for checked exceptions; listing unchecked ones simply documents them for readers.
Throw early, declare honestly
Professional code validates inputs at the top of public methods and throws IllegalArgumentException with a clear message. File and network utilities declare throws IOException, leaving the decision — retry, fallback, or fail — to the caller, who knows the context.
Key takeaways
- throw + an object: throw new X(...)
- throws + one or more types in the method signature
- Checked exceptions that escape a method must appear in throws
- An override can't declare new or broader checked exceptions
Checked exceptions are purely a compiler rule — the JVM itself never checks throws clauses. That's why Kotlin code can throw an IOException without declaring anything.
Practice questions
Which keyword fills the blank?
void setAge(int age) {
if (age < 0)
___ new IllegalArgumentException("age");
this.age = age;
}- throw
- throws
- raise
- return
Check your answer
throw. throw raises a specific exception object. Java has no raise keyword.
Which keyword fills the blank?
String load(Path p) ___ IOException {
return Files.readString(p);
}- throws
- throw
- catches
- extends
Check your answer
throws. Files.readString can throw IOException, a checked exception, so the method must declare it with throws (or catch it).