throw Keyword in Java – Explained with Examples
The throw keyword lets your own code raise an exception. When a method detects a situation it cannot or should not handle, such as an invalid argument, an impossible state or a failed operation, it creates an exception object and throws it. Control leaves the method immediately and passes to the nearest matching catch block.
This tutorial covers the syntax, throwing unchecked and checked exceptions, the standard exceptions to use for validation, rethrowing and wrapping exceptions, and the rules of throw.
1. Syntax
throw throwableObject;
throw new IllegalArgumentException("quantity must be positive");
The expression after throw must be an object of Throwable or a subclass. You usually create it right there with new and a helpful message.
2. Throwing an Unchecked Exception
public class ThrowBasics {
static void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Age must be between 0 and 150, got " + age);
}
System.out.println("Age set to " + age);
}
public static void main(String[] args) {
setAge(34);
try {
setAge(-5);
System.out.println("not printed");
} catch (IllegalArgumentException e) {
System.out.println("Rejected: " + e.getMessage());
}
}
}
Age set to 34 Rejected: Age must be between 0 and 150, got -5
The statement after setAge(-5) never ran: as soon as an exception is thrown, the rest of the method and the rest of the try block are skipped.
3. Throwing a Checked Exception
If you throw a checked exception, the method must declare it with throws (or catch it itself), and callers must handle it:
import java.io.FileNotFoundException;
public class ThrowChecked {
// Throwing a checked exception requires a throws clause
static String loadTemplate(String name) throws FileNotFoundException {
if (!name.endsWith(".html")) {
throw new FileNotFoundException("No template named " + name);
}
return "<h1>" + name + "</h1>";
}
public static void main(String[] args) {
for (String n : new String[] {"home.html", "home.txt"}) {
try {
System.out.println(loadTemplate(n));
} catch (FileNotFoundException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
}
<h1>home.html</h1> Error: No template named home.txt
Unchecked exceptions (RuntimeException subclasses) need no declaration. See throws keyword and throw vs throws.
4. Validating Arguments and State
Most throw statements in real code protect a method from bad input or misuse. The JDK's standard exceptions describe these problems clearly:
import java.util.Objects;
public class ValidationHelpers {
static final class Order {
private final String customer;
private final int quantity;
private boolean shipped;
Order(String customer, int quantity) {
this.customer = Objects.requireNonNull(customer, "customer must not be null");
if (quantity <= 0) throw new IllegalArgumentException("quantity must be positive");
this.quantity = quantity;
}
void ship() {
if (shipped) throw new IllegalStateException("order already shipped");
shipped = true;
System.out.println("Shipped " + quantity + " item(s) to " + customer);
}
}
public static void main(String[] args) {
Order o = new Order("Asha", 2);
o.ship();
try { o.ship(); } catch (IllegalStateException e) { System.out.println("IllegalStateException: " + e.getMessage()); }
try { new Order(null, 1); } catch (NullPointerException e) { System.out.println("NullPointerException: " + e.getMessage()); }
try { new Order("Ravi", 0); } catch (IllegalArgumentException e) { System.out.println("IllegalArgumentException: " + e.getMessage()); }
}
}
Shipped 2 item(s) to Asha IllegalStateException: order already shipped NullPointerException: customer must not be null IllegalArgumentException: quantity must be positive
| Exception | Throw it when… |
|---|---|
IllegalArgumentException | An argument has an invalid value |
NullPointerException | An argument is null but must not be (use Objects.requireNonNull) |
IllegalStateException | The object is not in the right state for this call |
IndexOutOfBoundsException | An index is outside the valid range (see Objects.checkIndex) |
UnsupportedOperationException | The operation is not supported by this object |
| A custom exception | A business rule is broken, for example insufficient balance |
5. Rethrowing and Wrapping
A catch block can throw too. Wrapping a low-level exception in one that makes sense to callers, while keeping the original as its cause, is a common and useful pattern:
public class RethrowWrap {
static class PaymentException extends Exception {
PaymentException(String message, Throwable cause) { super(message, cause); }
}
static int parseAmount(String text) {
return Integer.parseInt(text);
}
static void pay(String amountText) throws PaymentException {
try {
int amount = parseAmount(amountText);
System.out.println("Paid " + amount);
} catch (NumberFormatException e) {
throw new PaymentException("Payment failed for amount '" + amountText + "'", e); // wrap with cause
}
}
public static void main(String[] args) {
try {
pay("500");
pay("5O0");
} catch (PaymentException e) {
System.out.println(e.getMessage());
System.out.println("cause: " + e.getCause());
}
}
}
Paid 500 Payment failed for amount '5O0' cause: java.lang.NumberFormatException: For input string: "5O0"
To rethrow the same exception unchanged, simply write throw e; inside the catch block, for example after logging it.
6. Rules of throw
- Only
Throwableobjects can be thrown;throw "error";does not compile. - Throwing a checked exception requires catching it or declaring it with
throws. - Statements directly after
throwin the same block are unreachable and do not compile. - Throwing
nullcompiles but throws aNullPointerExceptioninstead. - One
throwstatement throws exactly one exception. - Since Java 14,
throwcan be used inside switch expression branches:default -> throw new IllegalArgumentException(...);.
7. Best Practices
- Throw early, at the point where the problem is detected.
- Write messages that include the bad value and what was expected.
- Prefer standard exceptions when they fit; create custom ones for domain problems.
- Always pass the original exception as the cause when wrapping.
- Do not throw generic
ExceptionorRuntimeException; be specific. - Document thrown exceptions with Javadoc
@throwstags.
8. Summary
throwraises an exception object and immediately leaves the current block.- Checked exceptions must be declared with
throwsor caught; unchecked ones need not be. - Use standard exceptions such as
IllegalArgumentExceptionandIllegalStateExceptionfor validation. - Rethrow or wrap exceptions in catch blocks, keeping the cause.
Related Tutorials
Frequently Asked Questions (FAQ)
Q1. What does the throw keyword do in Java?
It throws an exception object, stopping the current method and passing control to the nearest matching catch block up the call stack.
Q2. What can be thrown with throw?
Any object of type Throwable or its subclasses: exceptions and errors. You cannot throw strings, numbers or other objects.
Q3. Do I need throws when I use throw?
Only for checked exceptions. Throwing an unchecked exception such as IllegalArgumentException needs no throws clause.
Q4. Can I throw multiple exceptions at once?
No. A throw statement throws one exception. You can attach others as causes or suppressed exceptions if needed.
Q5. What happens to code after a throw statement?
It does not run. Code directly after throw in the same block is unreachable, and the compiler reports an error.
Q6. Can I rethrow an exception in a catch block?
Yes, with throw e;, or wrap it in another exception: throw new ServiceException("msg", e);.
Q7. Which exception should I throw for an invalid argument?
IllegalArgumentException, or NullPointerException if the argument is null (usually via Objects.requireNonNull).
Q8. What is IllegalStateException used for?
For methods called at the wrong time, when the object is in a state that does not allow the operation, such as shipping an order twice.
Q9. What happens if I throw null?
The JVM throws a NullPointerException instead.
Q10. Can I throw an exception from a constructor?
Yes. It prevents the object from being created, which is the right response to invalid constructor arguments.
Q11. Can I throw an exception from a static initializer?
Only unchecked exceptions, and the JVM wraps them in ExceptionInInitializerError, making the class unusable. Avoid failing static initialisation.
Q12. Can throw be used in a lambda?
Yes. Unchecked exceptions can be thrown freely. Checked exceptions can only be thrown if the functional interface's method declares them.
Q13. Can throw be used in a switch expression?
Yes, since Java 14: default -> throw new IllegalArgumentException("Unknown: " + value);.
Q14. Is it good practice to throw Exception?
No. Throw the most specific exception that describes the problem, so callers can handle it precisely.
Q15. What is exception chaining?
Throwing a new exception with the original one as its cause, using a constructor like new MyException(message, cause) or initCause(). Both appear in the stack trace.
Q16. How do I throw a custom exception?
Define a class that extends Exception or RuntimeException, then throw it: throw new InsufficientBalanceException(amount, balance);.
Q17. Where should I throw exceptions: early or late?
Early, as soon as you detect the problem. Failing fast makes the error message point to the real cause.
Q18. Does throwing exceptions slow down the program?
Creating an exception captures a stack trace, which costs some time. That is fine for exceptional situations but not for normal control flow.
Q19. Can a method both throw and catch the same exception?
Yes. A throw inside a try block can be caught by a catch block of the same try statement, although usually a plain if-else is clearer.
Q20. Should exception messages be user-friendly?
Exception messages are mainly for developers and logs: be precise and include values. Show users a separate, friendly message based on the exception.