Popular Searches
Popular Course Categories
Popular Courses

Applying throw and throws

Applying throw and throws

Exception Handling and Debugging

Applying throw and throws in Java

Course: Core Java Training

Topic: Applying throw and throws in Java

Course Link: Core Java Training Course

Demo Link: Register for a Course Demo

JustAcademy Website: Visit JustAcademy


1. Introduction to throw and throws

Exception handling is an important feature of Java that allows developers to manage errors and unexpected conditions during program execution. Java provides several keywords for exception handling, including try, catch, finally, throw, and throws.

The throw and throws keywords are closely related, but they serve different purposes. The throw keyword is used to explicitly throw a particular exception object, while the throws keyword declares the exception types that a method or constructor may pass to its caller.

Understanding these keywords helps developers validate input, communicate failures clearly, create custom exceptions, and design reliable Java applications.

2. Learning Objectives

  • Understand the purpose of the throw keyword.
  • Learn how the throws keyword works in method declarations.
  • Differentiate between throw and throws.
  • Understand how checked and unchecked exceptions behave.
  • Learn how to propagate exceptions between methods.
  • Use custom exceptions with throw and throws.
  • Understand common mistakes and exception-handling best practices.
  • Practice exception handling through Java programs and exercises.

3. What Is the throw Keyword?

The throw keyword is used to explicitly throw a throwable object from a method or code block. It is commonly used when a program detects an invalid value, a violated business rule, or another condition that should interrupt normal execution.

The object being thrown must be an instance of Throwable or one of its subclasses, such as Exception, RuntimeException, or Error.

Syntax

throw new ExceptionType("Descriptive error message");

In this syntax:

  • throw is the keyword used to throw the exception.
  • new creates an exception object.
  • ExceptionType is the class of the exception.
  • The message describes the reason for the failure.

Example: Using throw

public class ThrowExample {
    public static void main(String[] args) {
        int age = 16;

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

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

Output

Exception in thread "main" java.lang.IllegalArgumentException:
Age must be at least 18.

Explanation: The program checks whether the age is below 18. Because the condition is true, it throws an IllegalArgumentException. Since the exception is not caught, it propagates out of the main() method, and the statement that prints "Access granted." is not executed.

4. What Is the throws Keyword?

The throws keyword is used in a method or constructor declaration to specify exception types that the method may propagate to its caller. It is especially important for checked exceptions, which Java requires the program to catch or declare.

When a method declares a checked exception using throws, the caller must either handle the exception with an appropriate try-catch block or declare it in its own method signature.

Syntax

returnType methodName() throws ExceptionType {
    // Method statements
}

Example: Using throws

import java.io.IOException;

public class ThrowsExample {
    static void performOperation() throws IOException {
        throw new IOException("Unable to complete the operation.");
    }

    public static void main(String[] args) {
        try {
            performOperation();
        } catch (IOException e) {
            System.out.println("Handled: " + e.getMessage());
        }
    }
}

Output

Handled: Unable to complete the operation.

Explanation: The method performOperation() declares that it may throw an IOException. It explicitly throws the exception, and the calling method handles it using a catch block.

Important: The throws declaration does not itself throw an exception. It declares the types of exceptions that may be propagated from the method.

5. Difference Between throw and throws

Basis throw throws
Purpose Explicitly throws a throwable object. Declares throwable types that a method or constructor may propagate.
Location Inside a method, constructor, or code block. In a method or constructor declaration.
Followed by A throwable object or an expression that produces one. One or more exception types.
Number Throws one object at a time. Can declare multiple exception types separated by commas.
Checked exceptions A checked exception must be handled or declared. Can declare checked exceptions to satisfy the compiler requirement.
Unchecked exceptions Can throw unchecked exceptions explicitly. Unchecked exceptions can be declared, but the declaration is not required.
Example throw new IOException("Failed"); void read() throws IOException

6. Understanding Checked and Unchecked Exceptions

To use throw and throws correctly, it is important to understand the difference between checked and unchecked exceptions.

6.1 Checked Exceptions

Checked exceptions are checked by the compiler. A method must catch them or declare them if they may propagate beyond that method.

Common examples include:

  • IOException
  • FileNotFoundException
  • SQLException
  • ClassNotFoundException
  • InterruptedException

Example

import java.io.IOException;

public class CheckedExceptionExample {
    static void readData() throws IOException {
        throw new IOException("Data could not be read.");
    }

    public static void main(String[] args) {
        try {
            readData();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

The checked exception is declared by readData() and handled by its caller.

6.2 Unchecked Exceptions

Unchecked exceptions include RuntimeException and its subclasses. Java does not require methods to catch or declare these exceptions.

Common examples include:

  • ArithmeticException
  • NullPointerException
  • NumberFormatException
  • IllegalArgumentException
  • ArrayIndexOutOfBoundsException

Example

public class UncheckedExceptionExample {
    static void validateNumber(int number) {
        if (number < 0) {
            throw new IllegalArgumentException(
                "Number cannot be negative."
            );
        }
    }

    public static void main(String[] args) {
        try {
            validateNumber(-5);
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
    }
}

The method throws an unchecked exception when the argument is negative. It does not need a throws declaration, although the caller may still catch the exception.

7. Using throw and throws Together

The two keywords can be used together when a method explicitly throws a checked exception and declares that exception in its signature.

import java.io.IOException;

public class ThrowThrowsExample {
    static void checkFileStatus(boolean available)
            throws IOException {
        if (!available) {
            throw new IOException("The required file is unavailable.");
        }

        System.out.println("File is available.");
    }

    public static void main(String[] args) {
        try {
            checkFileStatus(false);
        } catch (IOException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

Output

Error: The required file is unavailable.

Step-by-Step Explanation

  1. The main() method calls checkFileStatus(false).
  2. The method checks whether the file is available.
  3. Since the argument is false, the method throws an IOException.
  4. The throws IOException declaration indicates that the checked exception may propagate to the caller.
  5. The catch block in main() handles the exception and prints its message.

8. Declaring Multiple Exceptions with throws

A method can declare more than one exception type in its throws clause. The exception types are separated by commas.

Syntax

void processData() throws IOException, SQLException {
    // Operations that may produce either exception
}

Example

import java.io.IOException;
import java.sql.SQLException;

public class MultipleThrowsExample {
    static void processData(boolean fileProblem, boolean databaseProblem)
            throws IOException, SQLException {
        if (fileProblem) {
            throw new IOException("File processing failed.");
        }

        if (databaseProblem) {
            throw new SQLException("Database operation failed.");
        }

        System.out.println("Data processed successfully.");
    }

    public static void main(String[] args) {
        try {
            processData(true, false);
        } catch (IOException e) {
            System.out.println("File error: " + e.getMessage());
        } catch (SQLException e) {
            System.out.println("Database error: " + e.getMessage());
        }
    }
}

Output

File error: File processing failed.

Explanation: The method declares both possible checked exception types. Because the first argument is true, it throws an IOException. The matching catch block handles the exception, and the second catch block is skipped.

9. Exception Propagation Using throws

Exception propagation occurs when a method does not handle an exception and allows it to move to its caller. The throws keyword can document this behavior and satisfy the compiler for checked exceptions.

import java.io.IOException;

public class ExceptionPropagationExample {
    static void methodC() throws IOException {
        throw new IOException("Failure in methodC.");
    }

    static void methodB() throws IOException {
        methodC();
    }

    static void methodA() throws IOException {
        methodB();
    }

    public static void main(String[] args) {
        try {
            methodA();
        } catch (IOException e) {
            System.out.println("Handled in main: " + e.getMessage());
        }
    }
}

Output

Handled in main: Failure in methodC.

Explanation

  • methodC() throws the exception.
  • methodB() allows it to propagate.
  • methodA() also allows it to propagate.
  • main() catches and handles the exception.

Exception propagation allows lower-level methods to report a failure without needing to decide how the application should respond. A higher-level method can then handle the problem in a way appropriate to the application.

10. Creating Custom Exceptions with throw and throws

Custom exceptions allow developers to represent specific business rules or application failures. A checked custom exception typically extends Exception, while an unchecked custom exception extends RuntimeException.

Example: Invalid Marks Exception

class InvalidMarksException extends Exception {
    public InvalidMarksException(String message) {
        super(message);
    }
}

public class StudentMarksExample {
    static void validateMarks(int marks)
            throws InvalidMarksException {
        if (marks < 0 || marks > 100) {
            throw new InvalidMarksException(
                "Marks must be between 0 and 100."
            );
        }

        System.out.println("Marks are valid.");
    }

    public static void main(String[] args) {
        try {
            validateMarks(120);
        } catch (InvalidMarksException e) {
            System.out.println("Validation failed: " + e.getMessage());
        }
    }
}

Output

Validation failed: Marks must be between 0 and 100.

Explanation

  • InvalidMarksException is a custom checked exception.
  • The method declares it using throws InvalidMarksException.
  • The method explicitly throws it when marks fall outside the valid range.
  • The caller handles the exception in a catch block.

11. Using throw in Constructors

The throw keyword can be used inside a constructor to reject invalid data when an object is created. This helps protect an object's state from being initialized with inappropriate values.

public class Product {
    private String name;
    private double price;

    public Product(String name, double price) {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException(
                "Product name cannot be empty."
            );
        }

        if (!Double.isFinite(price) || price <= 0) {
            throw new IllegalArgumentException(
                "Product price must be a finite positive value."
            );
        }

        this.name = name;
        this.price = price;
    }

    public void display() {
        System.out.println("Product: " + name);
        System.out.println("Price: " + price);
    }

    public static void main(String[] args) {
        try {
            Product product = new Product("Laptop", -500.0);
            product.display();
        } catch (IllegalArgumentException e) {
            System.out.println("Invalid product: " + e.getMessage());
        }
    }
}

Output

Invalid product: Product price must be a finite positive value.

Explanation: The constructor validates its arguments before assigning them to the object's fields. When the price is invalid, it throws an IllegalArgumentException, preventing creation of an invalid product object.

12. Using throw with Conditional Statements

Conditional statements are often used with throw to enforce validation rules. When a condition is violated, the program throws an exception rather than continuing with invalid data.

public class PasswordValidator {
    static void validatePassword(String password) {
        if (password == null) {
            throw new IllegalArgumentException(
                "Password cannot be null."
            );
        }

        if (password.length() < 8) {
            throw new IllegalArgumentException(
                "Password must contain at least 8 characters."
            );
        }

        System.out.println("Password format is valid.");
    }

    public static void main(String[] args) {
        try {
            validatePassword("abc");
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
    }
}

Output

Password must contain at least 8 characters.

This example demonstrates validation logic. A real authentication system should also apply secure password-storage practices and additional security checks.

13. Common Mistakes When Using throw and throws

Mistake Why It Is Incorrect Correct Approach
Using throw without a throwable object The keyword requires an object compatible with Throwable. Use throw new IllegalArgumentException("Invalid input");.
Using throws inside a method body throws belongs in the method or constructor declaration. Use throw to throw an exception inside the body.
Not handling a checked exception The compiler reports an error if a checked exception is neither caught nor declared. Add a suitable catch block or declare the exception with throws.
Assuming throws handles the exception The declaration does not handle an exception. Catch it at an appropriate level or allow it to propagate.
Declaring unnecessary exception types Unnecessary declarations can make APIs harder to understand. Declare only meaningful exception types.
Throwing generic exceptions for every failure The actual problem may become less clear. Use an appropriate standard exception or a meaningful custom exception.
Ignoring the original cause Diagnostic information may be lost when an exception is wrapped. Preserve the cause when translating exceptions.
Using exceptions for routine decisions Normal application logic becomes harder to follow. Use conditional statements for expected routine conditions when appropriate.

14. Best Practices for Using throw and throws

  • Use throw when a specific condition requires an exception to be raised.
  • Use throws to declare checked exceptions that may propagate to callers.
  • Choose meaningful exception classes rather than using one generic type for every problem.
  • Write clear and useful exception messages.
  • Validate arguments at suitable boundaries, such as public methods and constructors.
  • Use checked exceptions when callers are expected to handle a condition explicitly; use unchecked exceptions for appropriate programming-contract violations.
  • Catch exceptions at the layer that can recover or respond meaningfully.
  • Preserve the original cause when wrapping an exception.
  • Avoid empty catch blocks and do not silently ignore failures.
  • Do not catch Throwable or Error casually as a substitute for correct error handling.
  • Write tests for valid inputs, invalid inputs, and failure scenarios.

15. Practical Exercise 1: Age Validation

Task: Create a Java program that checks whether a person is eligible to register for an age-restricted service.

Requirements:

  • Create a method named validateAge().
  • Accept an integer age as a parameter.
  • Throw an IllegalArgumentException if the age is negative.
  • Throw an IllegalArgumentException if the age is below 18.
  • Use a catch block in main() to display the message.
  • Test the program with valid and invalid values.

16. Practical Exercise 2: File Reading

Task: Write a method that reads a text file and declares IOException using throws.

Requirements:

  • Use the Files.readString() method from java.nio.file.Files.
  • Declare throws IOException in the reading method.
  • Handle the exception in the calling method.
  • Display a useful message if the file cannot be read.
  • Test the program with an existing file and a missing file.

17. Practical Exercise 3: Custom Exception

Task: Create an InsufficientBalanceException class for a banking application.

Requirements:

  • Extend Exception.
  • Add a constructor that accepts a message.
  • Create a withdrawal method that declares the exception using throws.
  • Use throw when the requested withdrawal exceeds the balance.
  • Handle the exception in the calling code.
  • Display the remaining balance when the withdrawal succeeds.

18. Mini Project: Employee Salary Validation

Objective: Build a simple employee salary validation program that uses throw and throws to reject invalid salary values.

class InvalidSalaryException extends Exception {
    public InvalidSalaryException(String message) {
        super(message);
    }
}

public class EmployeeSalary {
    static void validateSalary(double salary)
            throws InvalidSalaryException {
        if (!Double.isFinite(salary) || salary <= 0) {
            throw new InvalidSalaryException(
                "Salary must be a finite positive amount."
            );
        }

        System.out.println("Salary accepted: " + salary);
    }

    public static void main(String[] args) {
        double salary = -25000.0;

        try {
            validateSalary(salary);
        } catch (InvalidSalaryException e) {
            System.out.println("Salary validation failed: " + e.getMessage());
        }
    }
}

Expected Output

Salary validation failed: Salary must be a finite positive amount.

Project Enhancements

  • Accept salary values from the user.
  • Validate that the salary is a finite positive number.
  • Display an appropriate message for invalid values.
  • Extend the project to calculate annual salary from monthly salary.
  • Add a custom exception for invalid employee identification numbers.
  • Write tests for valid, negative, zero, NaN, and infinite salary values.

19. Interview Questions and Answers

Q1. What is the difference between throw and throws in Java?

Answer: throw explicitly throws a throwable object, whereas throws declares the exception types that a method or constructor may propagate to its caller.

Q2. Can we use throw and throws together?

Answer: Yes. A method can declare a checked exception with throws and explicitly throw an instance of that exception using throw.

Q3. Can a method declare multiple exceptions using throws?

Answer: Yes. Multiple exception types can be declared in a method signature, separated by commas.

Q4. Is the throws keyword mandatory for unchecked exceptions?

Answer: No. Unchecked exceptions do not need to be declared, although Java permits their declaration.

Q5. Is the throw keyword used only for custom exceptions?

Answer: No. It can throw built-in exceptions, custom exceptions, and other throwable objects.

Q6. What happens when a checked exception is thrown without being caught or declared?

Answer: If a checked exception can propagate out of a method without being caught or declared, the compiler reports an error.

Q7. Does throws handle an exception?

Answer: No. It declares that an exception may propagate. Handling requires an appropriate catch block or another suitable mechanism at a higher level.

Q8. Can constructors use throws?

Answer: Yes. Constructors can declare checked exceptions using throws, and callers must handle or declare those exceptions.

Q9. Can throw be used inside a constructor?

Answer: Yes. A constructor can throw an exception when the supplied arguments violate validation rules.

Q10. Why are custom exceptions useful?

Answer: They represent application-specific failures clearly and allow callers to distinguish particular business conditions from other errors.

20. Quick Revision Checklist

  • throw explicitly throws a throwable object.
  • throws declares throwable types in a method or constructor signature.
  • A checked exception must be caught or declared.
  • Unchecked exceptions do not require a throws declaration.
  • A method can declare multiple exception types separated by commas.
  • Exceptions can propagate through multiple methods until a matching handler is found.
  • Custom exceptions can represent application-specific problems.
  • Constructors can validate input and throw exceptions.
  • Meaningful exception messages improve debugging.
  • Exception causes should be preserved when useful.
  • Test both successful execution and exceptional conditions.

21. Conclusion

The throw and throws keywords are fundamental tools for exception handling in Java. The throw keyword allows a program to raise an exception when a condition is violated, while throws declares exception types that may be passed to the calling method.

By using these keywords correctly, developers can validate input, create custom exceptions, propagate failures through method calls, and keep error-handling logic organized. Combining these techniques with clear messages, appropriate exception types, and thorough testing helps create more reliable Java applications.

Continue learning Java programming through the Core Java Training Course, register for a course demo, or visit the JustAcademy website.

Previous Next
whatsapp