Throw Exception in Java
Problem
The throw statement is what actually raises an exception at the exact point a failure is detected — it's the action, distinct from merely declaring that a method might fail.
Validate a quantity, and use throw to raise an exception the moment it turns out to be invalid.
Java Program
public class ThrowExceptionDemo {
static void validateQuantity(int quantity) {
if (quantity < 0) {
throw new IllegalArgumentException("Quantity cannot be negative: " + quantity);
}
System.out.println("Quantity accepted: " + quantity);
}
public static void main(String[] args) {
try {
validateQuantity(-3);
} catch (IllegalArgumentException e) {
System.out.println("Rejected: " + e.getMessage());
}
}
}Output
Core Logic
Checking the precondition first, and using throw the moment it fails, raises the exception at the exact line where the problem was actually detected.
- 1
validateQuantity(-3)checksquantity < 0before doing anything else with the value. - 2
throw new IllegalArgumentException(...)is the statement that actually creates the exception object and raises it right there — nothing happens after it in that method call. - 3The caller's
try/catchis what stops the exception from propagating further and crashing the program. - 4If the quantity had been valid,
throwwould never execute and the method would print its success message instead.
quantity = -3, the check fails immediately, so throw raises the exception, caught by the caller and printed as "Rejected: Quantity cannot be negative: -3".Key Point: throw is the single statement that actually raises an exception — a method's throws clause only declares that this might happen, it doesn't make anything happen on its own.
Key Concepts
Approach 2: Java 8
import java.util.Optional;
public class ThrowExceptionOptional {
static int validateQuantity(int quantity) {
return Optional.of(quantity)
.filter(q -> q >= 0)
.orElseThrow(() -> new IllegalArgumentException("Quantity cannot be negative: " + quantity)); // built only if the filter rejected the value
}
public static void main(String[] args) {
try {
int accepted = validateQuantity(-3);
System.out.println("Quantity accepted: " + accepted);
} catch (IllegalArgumentException e) {
System.out.println("Rejected: " + e.getMessage());
}
}
}
Output
Core Logic
Optional.filter().orElseThrow() expresses 'validate, then throw' as one chained expression instead of an explicit if-check followed by a separate throw statement.
- 1
Optional.of(quantity)wraps the value to be validated. - 2
.filter(q -> q >= 0)keeps it only if it's non-negative, becoming empty otherwise — the same condition the manualifcheck tested. - 3
.orElseThrow(() -> new IllegalArgumentException(...))returns the quantity if present, or invokes the lambda to build and throw the exception if the check failed. - 4The
throwkeyword is still there, just moved inside the lambda thatorElseThrow()calls when needed.
quantity = -3, the filter produces an empty Optional, so orElseThrow() invokes the lambda and raises the same exception, caught and printed identically.Key Point: The exception is only constructed if the Optional is actually empty — orElseThrow() defers building it until the moment it's needed, rather than always allocating it up front.