Topic 82 of 119 8. Exception Handling in Java Interactive Tutorial

Java throw Keyword: Explicit Exception Generation

9 mins read Last updated: 22 Aug 2026 29,186 views

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:

Main.java
Run Online
throw new ExceptionType("message");

For example:

Main.java
Run Online
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:

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:

Main.java
Run Online
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:

For example:

Main.java
Run Online
throw new RuntimeException("Something went wrong.");

You can also create the exception first:

Main.java
Run Online
RuntimeException error = new RuntimeException("Something went wrong.");
throw error;

Both approaches explicitly throw an exception.


Simple throw Example

Main.java
Run Online
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:

Main.java
Run Online
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.

Main.java
Run Online
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:

Main.java
Run Online
Exception handled: Something went wrong.

Here the flow is:

Main.java
Run Online
throw↓Exception created↓Exception thrown↓catch↓Exception handled

throw for Input Validation

One of the most common uses of throw is validating input.

Main.java
Run Online
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:

If the method is called with:

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:

Main.java
Run Online
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:

Main.java
Run Online
throw new RuntimeException("Invalid application state.");

However, using a more specific exception type is generally better when one clearly represents the problem.

For example:

Main.java
Run Online
throw new IllegalArgumentException("Invalid age.");

is usually more descriptive than:

Main.java
Run Online
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.

Main.java
Run Online
throw new IllegalArgumentException("Invalid price.");

IllegalStateException

Used when an object or application is in an inappropriate state for an operation.

Main.java
Run Online
throw new IllegalStateException("Account is already closed.");

NullPointerException

Can be explicitly thrown, although explicit use should be considered carefully.

Main.java
Run Online
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.

Main.java
Run Online
throw new UnsupportedOperationException( "This operation is not supported.");

Custom Exception

You can also create your own exception class:

Main.java
Run Online
class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
}

Then:

Main.java
Run Online
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.

Main.java
Run Online
throw new IllegalArgumentException("Invalid value.");

throws

throws is used in a method declaration to indicate that the method may propagate specified checked exceptions.

Main.java
Run Online
static void readFile() throws IOException {
    // File operation
}

A simple way to remember:

Main.java
Run Online
throw → Throws an exceptionthrows → Declares possible checked exceptions

Example of throw and throws Together

These keywords can be used in the same program.

Main.java
Run Online
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:

  • throw actually creates and throws the exception.

  • throws declares that the method may propagate an IOException.

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:

Main.java
Run Online
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.

Main.java
Run Online
class InsufficientBalanceException extends Exception {
    public InsufficientBalanceException(String message) {
        super(message);
    }
}

Then use it:

Main.java
Run Online
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:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        try {
            BankAccount.withdraw(1000, 1500);
        } catch (InsufficientBalanceException e) {
            System.out.println(e.getMessage());
        }
    }
}

Output:

Main.java
Run Online
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.

Main.java
Run Online
class InvalidOrderException extends RuntimeException {
    public InvalidOrderException(String message) {
        super(message);
    }
}

Then:

Main.java
Run Online
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.

Main.java
Run Online
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.

Main.java
Run Online
class Product {
    private double price;
    public Product(double price) {
        if (price < 0) {
            throw new IllegalArgumentException( "Price cannot be negative.");
        } this.price = price;
    }
}

Now:

Main.java
Run Online
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:

Main.java
Run Online
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.

Main.java
Run Online
if (username == null) {
    throw new IllegalArgumentException( "Username cannot be null.");
}

Another example:

Main.java
Run Online
if (quantity <= 0) {
    throw new IllegalArgumentException( "Quantity must be greater than zero.");
}

The pattern is simple:

Main.java
Run Online
Check condition↓Is value invalid?↓Yes↓throw↓Exception handling

throw 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:

Main.java
Run Online
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.

Main.java
Run Online
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:

Main.java
Run Online
Validation method↓Detect problem↓throw exception↓Caller↓Handle problem

This 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:

Main.java
Run Online
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.

Main.java
Run Online
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:

Main.java
Run Online
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:

Main.java
Run Online
throw new IllegalArgumentException("Invalid age.");

If different conditions can produce different exceptions, conditional logic can select which exception to throw:

Main.java
Run Online
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:

throw

Signals an exceptional condition:

Main.java
Run Online
throw new IllegalArgumentException("Invalid input.");

Think of them as:

Main.java
Run Online
return → Successful method resultthrow → Exceptional method result

This distinction is useful when designing method behavior.


throw and finally

The throw keyword can be used inside a try block with finally.

Main.java
Run Online
try {
    throw new RuntimeException("Something failed.");
} finally {
    System.out.println("Cleanup.");
}

Output normally includes:

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.

Main.java
Run Online
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:

Main.java
Run Online
Invalid age: Age must be at least18.Validation finished.

The flow is:

Main.java
Run Online
validateAge()↓condition fails↓throw↓catch↓finally

Best Practices for Using throw

1. Throw Specific Exceptions

Prefer:

Main.java
Run Online
throw new IllegalArgumentException("Invalid age.");

instead of:

Main.java
Run Online
throw new RuntimeException("Invalid age.");

when IllegalArgumentException accurately represents the problem.


2. Provide a Useful Message

Good:

Main.java
Run Online
throw new IllegalArgumentException( "Age must be between 18 and 100.");

Less useful:

Main.java
Run Online
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.

Main.java
Run Online
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:

Main.java
Run Online
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:

Main.java
Run Online
throw = declarationthrows = actual exception

The correct relationship is:

Main.java
Run Online
throw = explicitly throws an exception objectthrows = declares checked exceptions in a method signature

Mistake 2: Throwing Generic RuntimeException Everywhere

Avoid:

Main.java
Run Online
throw new RuntimeException("Invalid age.");

when a more specific exception is appropriate.

Prefer:

Main.java
Run Online
throw new IllegalArgumentException("Invalid age.");

Mistake 3: Throwing Without Useful Context

Avoid:

Main.java
Run Online
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:

Main.java
Run Online
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.

Main.java
Run Online
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:

Main.java
Run Online
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:

This example demonstrates how throw can enforce application-specific rules.


Real-World Example: API Validation

Imagine a service method that creates a user:

Main.java
Run Online
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.

Main.java
Run Online
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

KeywordPurpose
throwExplicitly throws an exception object
throwsDeclares checked exceptions that a method may propagate
tryContains code that may throw an exception
catchHandles a matching exception
finallyPerforms cleanup/final actions

A useful memory trick is:

Main.java
Run Online
throw → Do itthrows → Declare ittry → Attempt itcatch → Handle itfinally → Clean up

Frequently 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:

Main.java
Run Online
throw new ExceptionType("message");

Can throw be used with RuntimeException?

Yes. You can explicitly throw any appropriate runtime exception.

Main.java
Run Online
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.

Main.java
Run Online
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

Architecture Diagram
┌───────────────────┐
│ Check a condition │
└─────────┬─────────┘
↓
Is it invalid?
       /     \
     No       Yes
     │         │
     ▼         ▼
 Continue     throw
                │
                ▼
        Exception Object
                │
                ▼
          Exception Handler

Graphic 2 — throw vs throws

Create a two-column comparison:

Architecture Diagram
┌──────────────────┬─────────────────────┐
│ throw            │ throws              │
├──────────────────┼─────────────────────┤
│ Throws exception │ Declares exception  │
│ Used in method   │ Used in signature   │
│ Throws object    │ Lists exceptions    │
└──────────────────┴─────────────────────┘

Graphic 3 — Validation Example

Architecture Diagram
User Input
↓
Validate
↓
Valid? ───── Yes ───→ Continue
    │
    No
↓
throw Exception
↓
catch / Handle

Graphic 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+
Main.java
Run Online
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());
        }
    }
}

Common Java Technical Interview Questions & Answers

Interview Prep
Q1

What is the difference between throw and throws?

throw is used inside a method body to explicitly trigger an exception instance; throws is used in a method header signature to declare that the method may propagate checked exceptions.
Q2

Can you throw custom business exceptions?

Yes, by creating a class extending Exception or RuntimeException.

Key Takeaways, Best Practices & Clean Code Rules

Java Best Practice & Production Rules

Throw standard runtime exceptions (IllegalArgumentException, IllegalStateException) for invalid arguments and unexpected state.