Java throw Keyword Explained: Explicitly Throw Exceptions with Examples

0

So far, we have looked at how Java responds when an exception occurs. But sometimes an application needs to create an exceptional situation deliberately. For example, a method may receive an invalid age, an impossible transaction amount, or an object that violates an important business rule. Java provides the throw keyword for explicitly throwing an exception.


The key idea is simple: throw lets your program say, "This condition is invalid, so stop normal processing and raise an exception."


Why throw Exists

Not every exceptional condition is discovered automatically by the JVM. Many application rules are specific to the business domain.


For example, Java knows that dividing an integer by zero is invalid. But Java does not automatically know that your application considers an employee age below 18 invalid, an account balance below a certain threshold unacceptable, or an order with no items invalid.


Developers can use throw to turn such application-level violations into explicit exceptions.


Basic Syntax

throw exceptionObject;

The expression after throw must evaluate to an object that is compatible with Throwable.


Simple Example

public class ThrowDemo {
    public static void main(String[] args) {

        int age = 15;

        if (age < 18) {
            throw new IllegalArgumentException("Age must be at least 18.");
        }

        System.out.println("Access granted.");
    }
}

The program checks an application rule. When the condition is violated, it creates an IllegalArgumentException object and throws it explicitly.


Because the exception is not handled in this example, it propagates to the caller and eventually causes the program's execution to terminate.


Important: throw is used to actually throw an exception object. It is different from throws, which is used in a method declaration to indicate that a method may propagate exceptions.


throw with try-catch

An explicitly thrown exception can be handled using the same try-catch mechanism used for exceptions generated by the JVM.


public class ThrowHandledDemo {
    public static void main(String[] args) {

        int age = 15;

        try {
            if (age < 18) {
                throw new IllegalArgumentException(
                    "Age must be at least 18."
                );
            }

            System.out.println("Access granted.");

        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
    }
}

Here, the application explicitly throws the exception, and the catch block handles it. This makes the validation rule and its response easy to understand.


throw Creates an Exception Object

The most common form of throw creates an exception object and immediately throws it.


throw new IllegalArgumentException("Invalid amount.");

This single statement performs two conceptual operations: it creates an exception object and then throws that object.


You can also create the object separately.


IllegalArgumentException exception =
        new IllegalArgumentException("Invalid amount.");

throw exception;

Both approaches produce the same fundamental behavior.


Throwing Different Exception Types

The exception type should communicate what went wrong. Java provides many standard exception classes that can be used when they accurately describe the problem.


Exception Typical Use
IllegalArgumentException A method receives an inappropriate argument.
IllegalStateException An object or application is in an inappropriate state for an operation.
NullPointerException A required reference is unexpectedly null.
UnsupportedOperationException An operation is not supported by the current implementation.

Choose an exception based on the meaning of the failure rather than simply selecting the shortest class name.


Validation with throw

One of the most practical uses of throw is enforcing method contracts.


public static void setPercentage(int percentage) {

    if (percentage < 0 || percentage > 100) {
        throw new IllegalArgumentException(
            "Percentage must be between 0 and 100."
        );
    }

    System.out.println("Percentage accepted: " + percentage);
}

The method clearly defines what values it accepts. Invalid input is rejected immediately instead of allowing an invalid state to travel deeper into the application.


Why Fail Fast?

Explicitly throwing an exception at the point where invalid data is detected is often called fail-fast behavior. It prevents the program from continuing with data that is already known to be invalid.


public static void withdraw(double amount) {

    if (amount <= 0) {
        throw new IllegalArgumentException(
            "Withdrawal amount must be positive."
        );
    }

    // Continue with valid withdrawal logic
}

Without this validation, the method might continue processing an invalid amount and cause a more confusing failure later.


Remember: Failing early with a meaningful exception is often easier to debug than allowing invalid data to travel through several layers before something eventually breaks.


throw Inside a Method

A method can explicitly throw an exception when its input or current state violates the method's rules.


public static int squareRoot(int number) {

    if (number < 0) {
        throw new IllegalArgumentException(
            "Number cannot be negative."
        );
    }

    return (int) Math.sqrt(number);
}

The method refuses to continue when the input violates its contract. The caller can then decide whether to catch the exception or allow it to propagate.


throw and Control Flow

When the throw statement executes, normal execution of the current block stops immediately.


System.out.println("Before");

throw new IllegalStateException("Something is wrong.");

System.out.println("After");

The second print statement cannot execute because the exception interrupts the normal flow. If there is a matching handler higher in the call chain, control moves toward that handler.


throw with finally

An explicitly thrown exception also participates in normal exception-handling rules, including finally processing.


try {
    throw new IllegalStateException("Invalid state.");
} catch (IllegalStateException e) {
    System.out.println("Exception handled.");
} finally {
    System.out.println("Cleanup performed.");
}

The exception is explicitly thrown, caught by the matching catch block, and followed by execution of the finally block.


Throwing a Checked Exception

The throw keyword can also be used with checked exceptions. However, checked exceptions are subject to Java's compile-time rules.


public static void process() throws Exception {

    throw new Exception("Processing failed.");
}

Because Exception is a checked exception, the method must either handle it with a suitable catch block or declare that it may propagate using throws.


This distinction becomes important when comparing throw and throws.


throw vs throws

Feature throw throws
Purpose Actually throws an exception. Declares that a method may propagate exceptions.
Location Used inside method or code block. Used in a method declaration.
Operand Requires an exception object. Lists exception types.
Example throw new Exception(); void read() throws IOException

Using a Custom Exception

The throw keyword becomes especially useful when an application defines its own exception types for domain-specific failures.


class InsufficientBalanceException extends Exception {

    public InsufficientBalanceException(String message) {
        super(message);
    }
}

public class BankAccount {

    public static void withdraw(double balance, double amount)
            throws InsufficientBalanceException {

        if (amount > balance) {
            throw new InsufficientBalanceException(
                "Insufficient account balance."
            );
        }

        System.out.println("Withdrawal approved.");
    }
}

The application is now expressing a meaningful business failure rather than relying on a generic exception. This makes the code easier to understand and gives higher layers a precise failure type to handle.


Throwing the Same Exception Again

Sometimes a method catches an exception to perform local logging, cleanup, or translation and then throws it again so that a higher layer can make the final decision.


public static void process() {
    try {
        performOperation();
    } catch (RuntimeException e) {
        System.out.println("Operation failed locally.");
        throw e;
    }
}

public static void performOperation() {
    throw new IllegalStateException("Invalid operation.");
}

The statement throw e; rethrows the same exception object. This preserves the exception's identity and allows the failure to continue propagating.


Wrapping an Exception

Another common pattern is to throw a new exception while preserving the original exception as its cause. This is useful when moving between application layers and giving the failure a more meaningful domain context.


try {
    // Low-level operation
} catch (Exception e) {
    throw new IllegalStateException(
        "Unable to process customer request.", e
    );
}

The new exception communicates the higher-level meaning while the original exception remains available as the cause.


Common Beginner Mistakes

  • Confusing throw with throws.
  • Throwing generic exceptions when a more meaningful exception type exists.
  • Using exceptions for ordinary control flow that could be handled with simple conditions.
  • Throwing an exception without a useful message when the message would aid debugging.
  • Catching an exception and rethrowing a new exception without preserving the original cause.
  • Allowing invalid application state to continue instead of rejecting it at the point of detection.

Best Practices

  • Throw exceptions when an operation cannot safely continue.
  • Choose an exception type that accurately describes the failure.
  • Use clear exception messages that explain the violated condition.
  • Validate method arguments at appropriate boundaries.
  • Preserve the original cause when translating exceptions between layers.
  • Do not use exceptions as a substitute for normal application decisions.

Industry Insight: An exception is part of a method's communication contract. If a method rejects invalid input or cannot complete its responsibility, a well-chosen exception can communicate that failure far more clearly than returning an unexplained value such as -1 or null.


Interview Insights

A frequent interview question is: "What is the difference between throw and throws?" Remember the simplest distinction: throw is used to explicitly throw an exception object, while throws appears in a method declaration to indicate that the method may propagate specified exceptions.


Another useful interview point is that throw can be used for both checked and unchecked exceptions. Checked exceptions, however, must satisfy Java's compile-time handling or declaration requirements.


Quick Revision

Concept Key Idea
throw Explicitly throws an exception object.
Syntax throw exceptionObject;
Validation Useful for rejecting invalid arguments or application states.
Fail fast Stops invalid processing as soon as the problem is detected.
Rethrow Throws the same caught exception again using throw e;.
Exception wrapping Throws a new exception while preserving the original cause.
throw vs throws throw performs the throw; throws declares possible propagation.

The throw keyword gives developers direct control over when an exceptional condition should be raised. It is particularly valuable for enforcing business rules, validating method contracts, and communicating failures clearly between application layers. Once you understand how to create and rethrow exceptions, the next question is how a method communicates those exceptions to its caller, which leads naturally to the throws keyword.

Post a Comment

0Comments
Post a Comment (0)