throw vs throws: raising and declaring
The keyword difference, the handle-or-declare rule, and chaining exceptions.
throw raises an exception; throws declares it
throw is an executable statement that raises an exception:
public static double divide(int a, int b) {
if (b == 0) throw new ArithmeticException("divisor is zero");
return (double) a / b;
}
throws is a method-signature clause that declares that a method might propagate a checked exception:
public String readConfig(String path) throws IOException {
return Files.readString(Path.of(path)); // IOException from Files is checked
}
Callers of readConfig must now either:
- catch (IOException e) { ... } — handle it, or
- themselves declare throws IOException — pass it up
This is the handle-or-declare rule for checked exceptions.
Wrapping a lower-level exception as the cause lets higher-level code use a domain exception while preserving the original stack trace:
public User loadUser(int id) throws ServiceException {
try {
return db.query(id);
} catch (SQLException e) {
throw new ServiceException("could not load user " + id, e); // e is the cause
}
}
The cause is accessible via getCause() on the thrown exception.