[!NOTE] Sometimes, an operation is mathematically "successful", but logically invalid for your business logic.
For example, a user trying to withdraw $10,000 when they only have $5 in their bank account. The mathematical subtraction of 5 - 10000 will successfully result in -9995.
This is a business rule failure, not a Java compiler failure. We can force Java to treat this as a fatal error using the throw keyword.
The 'throw' Keyword (Manual Instigation)
The throw statement allows you to create a custom error instantly. By convention, you use this in conjunction with an if statement validating input parameters.
public class SecurityApp {
static void checkAge(int age) {
if (age < 18) {
// 1. Manually instantiate a new Error object and throw it at the JVM!
throw new ArithmeticException("Access denied - You must be at least 18 years old.");
} else {
System.out.println("Access granted - You are old enough!");
}
}
public static void main(String[] args) {
checkAge(15); // This will crash the app with our custom error message!
}
}
The 'throws' Keyword (Passing Responsibility)
Sometimes, you don't want to handle an exception inside a small utility method. If a readFile() method fails because the file is missing, it shouldn't be the utility method's job to decide what to show the user.
Using the throws keyword in a method signature warns anyone calling the method: "Hey, this method might explode with an error. I'm not going to catch it. If you call me, YOU must put me in a try-catch block."
import java.io.*;
public class Logger {
// 1. We declare that this method throws an exception.
// We do NOT use try-catch inside this method body.
public static void readSecureFile() throws FileNotFoundException {
File myObj = new File("non_existent_passwords.txt");
Scanner myReader = new Scanner(myObj); // Java knows this could fail
}
public static void main(String[] args) {
// 2. Because readSecureFile() is marked with 'throws',
// the compiler FORCES you to wrap the execution in a try-catch!
try {
readSecureFile();
} catch (FileNotFoundException e) {
System.out.println("The Main API routed a graceful 404 response to the user's browser.");
}
}
}
[!CAUTION] Checked Exceptions vs Unchecked Exceptions: Java requires you to handle (via try/catch or throws) "Checked" exceptions like
IOExceptionat compile time. However, logical "Unchecked" exceptions likeNullPointerExceptionorArithmeticExceptionare completely ignored by the compiler.
Designing Your Own Failure Rules
throw is how your code says, "This state is invalid and execution should not continue normally." throws is how a method declares that callers must be ready for a failure it does not handle itself.
Business Rule Example
class Wallet {
private double balance;
void spend(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive");
}
if (amount > balance) {
throw new IllegalStateException("Insufficient balance");
}
balance -= amount;
}
}
IllegalArgumentException means the caller passed a bad value. IllegalStateException means the object is not currently in a valid state for that operation.
When throws Is Useful
static String readConfig(Path path) throws IOException {
return Files.readString(path);
}
This utility method does not decide what the UI should show. It lets the caller choose whether to retry, show a message, or stop startup.
Common Mistakes
- Throwing generic
Exceptioninstead of a meaningful exception type. - Declaring
throwson many methods just to avoid thinking about error handling. - Using checked exceptions for simple programming mistakes.
- Writing exception messages that do not explain what went wrong.
Mini Practice
Create a withdraw method that throws one exception for invalid amount and another for insufficient balance. Then call it inside a try-catch block and print different messages for each case.
Practice Lab: Withdrawal Rules
Use exceptions to enforce business rules clearly.
- Create a
BankAccountclass with private balance. - Add a method
withdraw(double amount). - Throw
IllegalArgumentExceptionfor non-positive amount. - Throw
IllegalStateExceptionfor insufficient balance. - Call the method inside try-catch and print different messages for each failure.
Goal: Separate invalid arguments from invalid object state.
Revision Checkpoint
throw: Actively raises an exception now.throws: Declares that a method may pass an exception to callers.- Bad argument: Often
IllegalArgumentException. - Bad state: Often
IllegalStateException. - Checked exception: Must be handled or declared.
Before the quiz: Decide whether a failure should be handled inside the method or by the caller.