throws Keyword in Java – Explained with Examples
The throws keyword appears in a method declaration and lists the checked exceptions the method may throw instead of handling itself. It is a promise to callers: "this method can fail in these ways, so be ready." The compiler then makes sure every caller either catches those exceptions or declares them in turn.
This tutorial explains when throws is required, how exceptions are passed up the call chain, how to declare several exceptions, and the rules for overriding methods.
1. Syntax
returnType methodName(parameters) throws ExceptionType1, ExceptionType2 {
// ...
}
String readConfig(Path path) throws IOException { ... }
2. Why throws Is Needed
Java's catch-or-declare rule says that code that can throw a checked exception must either catch it or declare it. If you do neither, the code does not compile:
Bad.java:2: error: unreported exception IOException; must be caught or declared to be thrown
public class Bad { static String r() { return Files.readString(Path.of("x")); } }
^
1 error
Adding throws IOException to the method declares the exception and moves the responsibility for handling it to the caller:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ThrowsBasics {
// This method does not handle IOException itself: it declares it
static String readConfig(Path path) throws IOException {
return Files.readString(path);
}
public static void main(String[] args) {
try {
System.out.println(readConfig(Path.of("missing-config.properties")));
} catch (IOException e) { // the caller handles it
System.out.println("Config not loaded: " + e.getClass().getSimpleName() + " - " + e.getMessage());
}
}
}
Config not loaded: NoSuchFileException - missing-config.properties
NoSuchFileException is a subclass of IOException, so declaring and catching IOException covers it.
3. Passing Exceptions Up the Call Chain
A method that calls a throws method can also declare the exception, passing it further up. The exception is finally handled by the method that knows what to do about it:
public class PassingUp {
static class StockException extends Exception {
StockException(String message) { super(message); }
}
static void reserve(String item, int qty) throws StockException {
if (qty > 5) throw new StockException("Only 5 " + item + "s in stock");
System.out.println("Reserved " + qty + " " + item + "(s)");
}
static void placeOrder(String item, int qty) throws StockException { // passes it up again
System.out.println("Placing order for " + item);
reserve(item, qty);
System.out.println("Order placed");
}
public static void main(String[] args) {
try {
placeOrder("lamp", 2);
placeOrder("chair", 9);
} catch (StockException e) {
System.out.println("Order failed: " + e.getMessage());
}
}
}
Placing order for lamp Reserved 2 lamp(s) Order placed Placing order for chair Order failed: Only 5 chairs in stock
"Order placed" was not printed for the chair: when reserve() threw, both reserve() and placeOrder() ended immediately, and main() handled the problem.
4. Declaring Several Exceptions
List several exception types separated by commas. Callers can catch them separately or together:
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class MultipleThrows {
// A method can declare several exceptions, separated by commas
static String fetch(String address) throws URISyntaxException, IOException {
URI uri = new URI(address);
if (uri.getHost() == null) throw new IOException("No host in " + address);
return "content of " + uri.getHost();
}
public static void main(String[] args) {
for (String a : new String[] {"https://example.com/page", "not a uri", "file:///tmp/x"}) {
try {
System.out.println(fetch(a));
} catch (URISyntaxException e) {
System.out.println("Bad address: " + e.getMessage());
} catch (IOException e) {
System.out.println("Fetch failed: " + e.getMessage());
}
}
}
}
content of example.com Bad address: Illegal character in path at index 3: not a uri Fetch failed: No host in file:///tmp/x
5. throws and Unchecked Exceptions
Declaring unchecked exceptions (RuntimeException subclasses) is allowed but not required, and the compiler does not force callers to handle them. Some APIs declare them anyway as documentation, but the usual way to document unchecked exceptions is the Javadoc @throws tag.
6. throws and Method Overriding
An overriding method may throw fewer or narrower checked exceptions than the method it overrides, but never new or broader ones. Otherwise code written against the parent type would receive exceptions it was never told about:
import java.io.FileNotFoundException;
import java.io.IOException;
public class OverridingRules {
static class Reader {
String read() throws IOException { return "base"; }
}
static class FileBasedReader extends Reader {
@Override
String read() throws FileNotFoundException { // narrower checked exception: allowed
return "file";
}
}
static class MemoryReader extends Reader {
@Override
String read() { // no exception at all: allowed
return "memory";
}
// String read() throws Exception { ... } // broader exception: compile error
}
public static void main(String[] args) throws IOException {
Reader[] readers = {new Reader(), new FileBasedReader(), new MemoryReader()};
for (Reader r : readers) System.out.println(r.read());
}
}
base file memory
| Overriding method declares… | Allowed? |
|---|---|
| The same checked exception | Yes |
| A subclass of it (narrower) | Yes |
| No exception | Yes |
| Any unchecked exception | Yes |
A broader checked exception (e.g. Exception) | No |
| An unrelated new checked exception | No |
7. Declaring throws on main
public static void main(String[] args) throws Exception compiles, and any exception then ends the program with a stack trace. It is acceptable for small demos and scripts, but real applications should handle exceptions and report them clearly.
8. Best Practices
- Declare specific exception types, not
throws Exception. - Declare an exception only if callers can reasonably respond to it; otherwise handle it or wrap it.
- At layer boundaries, translate low-level exceptions (such as
SQLException) into exceptions that fit the layer. - Document each declared exception with a Javadoc
@throwstag explaining when it occurs.
9. Summary
throwsin a method declaration lists exceptions the method may throw.- It is required for checked exceptions that are not caught inside the method.
- Callers must catch the declared checked exceptions or declare them too.
- Several exceptions can be declared, separated by commas.
- Overriding methods may declare fewer or narrower checked exceptions, never broader ones.
Related Tutorials
Frequently Asked Questions (FAQ)
Q1. What is the throws keyword in Java?
A keyword used in a method declaration to list the exceptions the method may throw, so that callers know to handle them.
Q2. When is throws required?
When a method can throw a checked exception (directly or by calling another method) and does not catch it.
Q3. Is throws needed for unchecked exceptions?
No. Unchecked exceptions may be declared for documentation, but it is not required and the compiler does not enforce handling.
Q4. What does "unreported exception; must be caught or declared to be thrown" mean?
Your code calls something that can throw a checked exception, but neither catches it nor declares it. Add a try-catch or a throws clause.
Q5. Can a method declare multiple exceptions?
Yes, separate them with commas: void load() throws IOException, SQLException.
Q6. Does throws handle the exception?
No. It only declares that the exception may occur and passes the responsibility to the caller. Handling happens in a catch block somewhere up the call chain.
Q7. Can an overriding method throw more exceptions?
Not more or broader checked exceptions. It may throw the same, narrower or no checked exceptions, and any unchecked exceptions.
Q8. Can a constructor use throws?
Yes. A constructor can declare checked exceptions, and code that calls new must handle them.
Q9. Can main() declare throws?
Yes. If an exception reaches the JVM from main(), the program ends with a stack trace. It is fine for demos but not for production code.
Q10. Is it bad to write throws Exception?
Usually yes. It forces callers to handle every possible exception and hides which failures can really happen. Declare specific types.
Q11. What is the difference between throw and throws?
throw is a statement that throws one exception object. throws is part of a method signature that declares possible exceptions. See throw vs throws.
Q12. Do I need to declare a subclass if I declare its parent?
No. Declaring IOException also covers FileNotFoundException and other subclasses.
Q13. Can interface methods declare throws?
Yes. Implementing classes may then throw those exceptions, narrower ones, or none.
Q14. Why can't lambdas throw checked exceptions easily?
Functional interfaces like Function do not declare checked exceptions, so a lambda body cannot throw them. Catch the exception inside the lambda or use a custom functional interface that declares it.
Q15. Is throws part of the method signature?
It is part of the method declaration but not of the signature used for overloading. Two methods cannot differ only in their throws clauses.
Q16. Should I catch or declare an exception?
Catch it if your method can handle it meaningfully. Declare it if a caller is in a better position to decide what to do.
Q17. Can a method declare an exception it never throws?
Yes, it compiles. This is sometimes done to allow subclasses or future versions to throw it, but unnecessary declarations burden callers.
Q18. How do I document exceptions properly?
Use Javadoc @throws ExceptionType description for every checked and important unchecked exception, explaining when it is thrown.
Q19. What happens if a declared exception is never caught?
If it reaches main() and is declared there too, the thread terminates with a stack trace when the exception occurs.
Q20. Do frameworks avoid checked exceptions?
Many modern frameworks, such as Spring, prefer unchecked exceptions and translate checked ones (like SQLException) into runtime exceptions to reduce throws clauses.