throw new ExceptionType("message");Java throw Keyword: Explicit Exception Generation
Direct Answer & Core Concept
Java normally generates exceptions automatically when certain problems occur during program execution. For example, dividing an integer by zero can cause an ArithmeticException, while converting invalid text to an integer can cause a NumberFormatException.
However, Java also allows developers to explicitly generate an exception when a program detects an invalid condition.
The throw keyword is used for this purpose. It gives developers direct control over when an exception should be created and sent through the normal Java exception-handling mechanism.
Detailed Explanation & Mechanics
What Is the throw Keyword in Java?
The Java throw keyword is used to explicitly throw an exception object.
Basic syntax:
For example:
public class Main {
public static void main(String[] args) {
int age = 15;
if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or older.");
} System.out.println("Access allowed.");
}
}The program explicitly creates and throws an IllegalArgumentException when the condition is invalid.
Why Use throw?
The throw keyword is useful when Java itself does not automatically detect the business rule that your application wants to enforce.
For example, Java knows how to detect division by zero:
int result = 10 / 0;But Java does not automatically know that your application requires a user's age to be at least 18.
You can enforce that rule yourself:
if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or older.");
}This makes throw especially useful for:
Input validation
Business rules
API validation
Method contracts
Custom application errors
Invalid object state
Security and authorization checks
Basic Syntax of throw
The basic syntax is:
throw exceptionObject;For example:
throw new RuntimeException("Something went wrong.");You can also create the exception first:
RuntimeException error = new RuntimeException("Something went wrong.");
throw error;Both approaches explicitly throw an exception.
Simple throw Example
public class Main {
public static void main(String[] args) {
throw new RuntimeException("This exception was created explicitly.");
}
}The program terminates with a runtime exception because there is no matching exception handler.
A typical output includes:
Exception in thread "main" java.lang.RuntimeException:This exception was created explicitly.The exact stack-trace formatting can vary by Java version and environment.
throw with try-catch
The throw keyword becomes more useful when combined with try-catch.
public class Main {
public static void main(String[] args) {
try {
throw new RuntimeException("Something went wrong.");
} catch (RuntimeException e) {
System.out.println("Exception handled: " + e.getMessage());
}
}
}Output:
Exception handled: Something went wrong.Here the flow is:
throw↓Exception created↓Exception thrown↓catch↓Exception handledthrow for Input Validation
One of the most common uses of throw is validating input.
public class Main {
static void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException( "Age cannot be negative.");
} System.out.println("Age: " + age);
} public static void main(String[] args) {
setAge(25);
}
}Output:
Age: 25If the method is called with:
setAge(-5);the method explicitly throws an IllegalArgumentException.
This is much clearer than allowing an invalid value to continue through the application.
throw with IllegalArgumentException
IllegalArgumentException is commonly used when a method receives an inappropriate argument.
Example:
public class Calculator {
static double calculateDiscount(double price, double discount) {
if (price < 0) {
throw new IllegalArgumentException( "Price cannot be negative.");
} if (discount < 0 || discount > 100) {
throw new IllegalArgumentException( "Discount must be between 0 and 100.");
} return price -(price * discount / 100);
}
}The method clearly defines which arguments are invalid.
throw and RuntimeException
RuntimeException is an unchecked exception.
You can explicitly throw it:
throw new RuntimeException("Invalid application state.");However, using a more specific exception type is generally better when one clearly represents the problem.
For example:
throw new IllegalArgumentException("Invalid age.");is usually more descriptive than:
throw new RuntimeException("Invalid age.");Specific exception types communicate the nature of the problem to other developers.
Common Exceptions Used with throw
Several standard Java exception classes are commonly used with throw.
IllegalArgumentException
Used when a method receives an invalid argument.
throw new IllegalArgumentException("Invalid price.");IllegalStateException
Used when an object or application is in an inappropriate state for an operation.
throw new IllegalStateException("Account is already closed.");NullPointerException
Can be explicitly thrown, although explicit use should be considered carefully.
throw new NullPointerException("Value cannot be null.");For many APIs, Objects.requireNonNull() can provide clearer null validation.
UnsupportedOperationException
Useful when an operation is deliberately not supported.
throw new UnsupportedOperationException( "This operation is not supported.");Custom Exception
You can also create your own exception class:
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}Then:
throw new InvalidAgeException("Age is invalid.");Custom exceptions are particularly useful when an application has domain-specific failure conditions.
throw vs throws
One of the most important Java concepts is the difference between throw and throws.
throw
throw is used to actually throw one exception object.
throw new IllegalArgumentException("Invalid value.");throws
throws is used in a method declaration to indicate that the method may propagate specified checked exceptions.
static void readFile() throws IOException {
// File operation
}A simple way to remember:
throw → Throws an exceptionthrows → Declares possible checked exceptionsExample of throw and throws Together
These keywords can be used in the same program.
import java.io.IOException;
public class Main {
static void process(int age) throws IOException {
if (age < 18) {
throw new IllegalArgumentException( "Age must be at least 18.");
} throw new IOException("Example checked exception.");
} public static void main(String[] args) {
try {
process(20);
} catch (IOException e) {
System.out.println("IO error: " + e.getMessage());
}
}
}Here:
throwactually creates and throws the exception.throwsdeclares that the method may propagate anIOException.
IllegalArgumentException is unchecked, so it does not need to be declared with throws.
Throwing a Checked Exception
Java allows you to explicitly throw checked exceptions as well.
For example:
import java.io.IOException;
public class Main {
static void checkFile() throws IOException {
boolean fileExists = false;
if (!fileExists) {
throw new IOException("File does not exist.");
}
} public static void main(String[] args) {
try {
checkFile();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}Because IOException is checked, the method must either:
catch it, or
declare it with
throws.
Throwing a Custom Checked Exception
You can create a custom checked exception by extending Exception.
class InsufficientBalanceException extends Exception {
public InsufficientBalanceException(String message) {
super(message);
}
}Then use it:
class BankAccount {
static void withdraw(double balance, double amount) throws InsufficientBalanceException {
if (amount > balance) {
throw new InsufficientBalanceException( "Insufficient account balance.");
} System.out.println("Withdrawal successful.");
}
}Calling code can handle it:
public class Main {
public static void main(String[] args) {
try {
BankAccount.withdraw(1000, 1500);
} catch (InsufficientBalanceException e) {
System.out.println(e.getMessage());
}
}
}Output:
Insufficient account balance.This is a practical example of using throw for a business-specific rule.
Throwing a Custom Unchecked Exception
A custom exception can also extend RuntimeException.
class InvalidOrderException extends RuntimeException {
public InvalidOrderException(String message) {
super(message);
}
}Then:
public class OrderService {
static void placeOrder(int quantity) {
if (quantity <= 0) {
throw new InvalidOrderException( "Order quantity must be greater than zero.");
} System.out.println("Order placed.");
}
}Because the custom exception extends RuntimeException, it is unchecked.
throw Inside a Method
A method can explicitly throw an exception when an invalid condition is detected.
static void registerUser(String username) {
if (username == null || username.isBlank()) {
throw new IllegalArgumentException( "Username cannot be empty.");
} System.out.println("User registered.");
}The method protects itself from receiving invalid input.
This is especially useful for reusable methods and APIs.
throw in Constructors
The throw keyword can also be used inside constructors to prevent invalid objects from being created.
class Product {
private double price;
public Product(double price) {
if (price < 0) {
throw new IllegalArgumentException( "Price cannot be negative.");
} this.price = price;
}
}Now:
Product product = new Product(-100);causes an IllegalArgumentException.
This protects the object from being created with an invalid state.
throw for Business Rules
Business applications often have rules that Java cannot automatically enforce.
For example:
static void transfer(double balance, double amount) {
if (amount <= 0) {
throw new IllegalArgumentException( "Transfer amount must be greater than zero.");
} if (amount > balance) {
throw new IllegalStateException( "Insufficient balance.");
} System.out.println("Transfer completed.");
}The application explicitly generates exceptions when business rules are violated.
This is one of the most important real-world uses of throw.
throw with Conditional Logic
throw is often placed inside an if statement.
if (username == null) {
throw new IllegalArgumentException( "Username cannot be null.");
}Another example:
if (quantity <= 0) {
throw new IllegalArgumentException( "Quantity must be greater than zero.");
}The pattern is simple:
Check condition↓Is value invalid?↓Yes↓throw↓Exception handlingthrow and Exception Propagation
When an exception is thrown inside a method and that method does not handle it, the exception can propagate to its caller.
Example:
static void validate(int age) {
if (age < 18) {
throw new IllegalArgumentException( "Age must be at least 18.");
}
}public static void main(String[] args) {
validate(15);
}The exception leaves validate() and propagates to the caller.
If the caller does not handle it, it can continue propagating up the call stack until a matching handler is found or the program terminates.
Handling a Thrown Exception at a Higher Level
The method that throws an exception does not always need to catch it immediately.
static void validateAge(int age) {
if (age < 18) {
throw new IllegalArgumentException( "Age must be at least 18.");
}
}public static void main(String[] args) {
try {
validateAge(15);
} catch (IllegalArgumentException e) {
System.out.println("Validation failed.");
}
}This creates a useful separation:
Validation method↓Detect problem↓throw exception↓Caller↓Handle problemThis pattern is common in layered applications.
throw and Stack Trace
When an exception is explicitly thrown, Java records information about where the exception was created and thrown.
Example:
static void validate() {
throw new IllegalArgumentException("Invalid value.");
}If the exception is not handled, the stack trace can show the method and line where the exception originated.
This information is useful for debugging.
Throwing an Existing Exception Object
You do not always have to create the exception directly in the throw statement.
IllegalArgumentException error = new IllegalArgumentException("Invalid value.");
throw error;The variable contains an exception object, which is then explicitly thrown.
This can be useful when an exception object needs to be prepared before being thrown.
Can You Throw null?
Java syntax allows an expression of a throwable type to be used with throw, but attempting to throw a null reference results in a NullPointerException.
For example:
RuntimeException error = null;
throw error;This results in a NullPointerException.
Therefore, a throw statement should normally receive an actual exception object.
Can You Throw Multiple Exceptions?
A single throw statement throws one exception object.
For example:
throw new IllegalArgumentException("Invalid age.");If different conditions can produce different exceptions, conditional logic can select which exception to throw:
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative.");
}if (age < 18) {
throw new IllegalStateException("User is underage.");
}Only one of these statements is reached for a particular execution path.
throw vs return
throw and return both change the normal execution flow, but they have completely different purposes.
return
Returns a value from a method:
return result;throw
Signals an exceptional condition:
throw new IllegalArgumentException("Invalid input.");Think of them as:
return → Successful method resultthrow → Exceptional method resultThis distinction is useful when designing method behavior.
throw and finally
The throw keyword can be used inside a try block with finally.
try {
throw new RuntimeException("Something failed.");
} finally {
System.out.println("Cleanup.");
}Output normally includes:
Cleanup.followed by propagation of the exception if it is not caught.
This demonstrates how explicit exception generation interacts with the cleanup mechanism provided by finally.
throw and try-catch-finally
All three concepts can work together.
public class Main {
static void validateAge(int age) {
if (age < 18) {
throw new IllegalArgumentException( "Age must be at least 18.");
}
} public static void main(String[] args) {
try {
validateAge(15);
} catch (IllegalArgumentException e) {
System.out.println("Invalid age: " + e.getMessage());
} finally {
System.out.println("Validation finished.");
}
}
}Output:
Invalid age: Age must be at least18.Validation finished.The flow is:
validateAge()↓condition fails↓throw↓catch↓finallyBest Practices for Using throw
1. Throw Specific Exceptions
Prefer:
throw new IllegalArgumentException("Invalid age.");instead of:
throw new RuntimeException("Invalid age.");when IllegalArgumentException accurately represents the problem.
2. Provide a Useful Message
Good:
throw new IllegalArgumentException( "Age must be between 18 and 100.");Less useful:
throw new IllegalArgumentException("Error");A clear message helps developers understand why the operation failed.
3. Validate Early
Check invalid input near the boundary where it enters your method or component.
static void createUser(String name) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException( "Name cannot be empty.");
} // Continue with valid input
}This prevents invalid data from traveling deeper into the application.
4. Do Not Use Exceptions for Ordinary Decisions
Avoid using throw as a replacement for normal if-else logic.
Use exceptions when an operation cannot reasonably continue because an invalid or exceptional condition has occurred.
5. Preserve the Original Cause When Wrapping Exceptions
Sometimes an application catches one exception and converts it into another abstraction.
For example:
try {
// Database operation
} catch (Exception e) {
throw new RuntimeException("Database operation failed.", e);
}The original exception is passed as the cause.
This preserves useful diagnostic information.
Common Mistakes with throw
Mistake 1: Confusing throw with throws
Incorrect understanding:
throw = declarationthrows = actual exceptionThe correct relationship is:
throw = explicitly throws an exception objectthrows = declares checked exceptions in a method signatureMistake 2: Throwing Generic RuntimeException Everywhere
Avoid:
throw new RuntimeException("Invalid age.");when a more specific exception is appropriate.
Prefer:
throw new IllegalArgumentException("Invalid age.");Mistake 3: Throwing Without Useful Context
Avoid:
throw new IllegalArgumentException("Error");Prefer a message that explains what is invalid.
Mistake 4: Using throw for Normal Control Flow
Exceptions should represent conditions that prevent normal processing, not ordinary branching.
Mistake 5: Losing the Original Cause
When converting one exception into another, preserve the original exception where appropriate:
throw new RuntimeException("Operation failed.", e);rather than discarding it.
Real-World Example: Bank Account
Here is a simple example of using throw for business validation.
class BankAccount {
private double balance;
public BankAccount(double balance) {
if (balance < 0) {
throw new IllegalArgumentException( "Initial balance cannot be negative.");
} this.balance = balance;
} public void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException( "Withdrawal amount must be positive.");
} if (amount > balance) {
throw new IllegalStateException( "Insufficient balance.");
} balance -= amount;
System.out.println("Withdrawal successful.");
}
}Usage:
public class Main {
public static void main(String[] args) {
try {
BankAccount account = new BankAccount(1000);
account.withdraw(1200);
} catch (IllegalArgumentException | IllegalStateException e) {
System.out.println(e.getMessage());
}
}
}Output:
Insufficient balance.This example demonstrates how throw can enforce application-specific rules.
Real-World Example: API Validation
Imagine a service method that creates a user:
static void createUser(String username, int age) {
if (username == null || username.isBlank()) {
throw new IllegalArgumentException( "Username is required.");
} if (age < 18) {
throw new IllegalArgumentException( "User must be at least 18 years old.");
} System.out.println("User created.");
}The method rejects invalid data immediately.
In larger applications, the exception can then be translated by an appropriate application layer into a user-friendly error response.
Real-World Example: Constructor Validation
Constructors can use throw to protect object validity.
class Employee {
private String name;
private double salary;
Employee(String name, double salary) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException( "Employee name is required.");
} if (salary < 0) {
throw new IllegalArgumentException( "Salary cannot be negative.");
} this.name = name;
this.salary = salary;
}
}This prevents the creation of an object with obviously invalid values.
Quick Comparison
| Keyword | Purpose |
|---|---|
throw | Explicitly throws an exception object |
throws | Declares checked exceptions that a method may propagate |
try | Contains code that may throw an exception |
catch | Handles a matching exception |
finally | Performs cleanup/final actions |
A useful memory trick is:
throw → Do itthrows → Declare ittry → Attempt itcatch → Handle itfinally → Clean upFrequently Asked Questions
What is the throw keyword in Java?
The throw keyword explicitly throws an exception object from a Java program.
What is the syntax of throw?
The basic syntax is:
throw new ExceptionType("message");Can throw be used with RuntimeException?
Yes. You can explicitly throw any appropriate runtime exception.
throw new IllegalArgumentException("Invalid input.");Can throw be used with checked exceptions?
Yes. If a checked exception is thrown from a method, it generally must be caught or declared with throws.
What is the difference between throw and throws?
throw actually throws an exception object. throws appears in a method declaration to indicate checked exceptions that may be propagated by that method.
Can I throw a custom exception?
Yes. You can create a custom exception class and throw an instance of it.
Can I throw an exception inside a constructor?
Yes. Constructors can use throw to reject invalid arguments or prevent an invalid object state.
Can throw be used inside catch?
Yes.
try {
// Code
} catch (Exception e) {
throw new RuntimeException("Operation failed.", e);
}This is often used to add context while preserving the original cause.
Does throw stop normal execution?
Yes. Once an exception is thrown, normal execution of the current flow stops and Java searches for an appropriate exception handler.
Graphics and Design Ideas
Graphic 1 — throw Execution Flow
┌───────────────────┐
│ Check a condition │
└─────────┬─────────┘
↓
Is it invalid?
/ \
No Yes
│ │
▼ ▼
Continue throw
│
▼
Exception Object
│
▼
Exception HandlerGraphic 2 — throw vs throws
Create a two-column comparison:
┌──────────────────┬─────────────────────┐
│ throw │ throws │
├──────────────────┼─────────────────────┤
│ Throws exception │ Declares exception │
│ Used in method │ Used in signature │
│ Throws object │ Lists exceptions │
└──────────────────┴─────────────────────┘Graphic 3 — Validation Example
User Input
↓
Validate
↓
Valid? ───── Yes ───→ Continue
│
No
↓
throw Exception
↓
catch / HandleGraphic 4 — Java Exception Keywords
Create four simple cards:
try
Attempt risky code.
catch
Handle an exception.
throw
Explicitly generate an exception.
finally
Perform cleanup.
This visual can help beginners understand how the major Java exception-handling keywords work together.
Runnable Code Example: Java throw Keyword
Java 17+public class ThrowDemo {
public static void validateAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative: " + age);
} System.out.println("Valid age registered: " + age);
} public static void main(String[] args) {
try {
validateAge(-5);
} catch (IllegalArgumentException e) {
System.err.println("Validation error: " + e.getMessage());
}
}
}