throws Keyword: Declaring Exceptions in Methods

The throws keyword is used in method declarations to indicate that a method can throw specific exceptions. This keyword informs the caller of the method that it might throw certain types of exceptions, and it must be prepared to handle them. Essentially, it acts as a contract between the method and the caller, ensuring that the caller is aware of the potential exceptions that could be raised.

When to Use throws

The throws keyword is typically used when:

  1. A method contains code that might raise checked exceptions.
  2. You want to delegate the responsibility of handling an exception to the calling method.
  3. You want to keep a method’s implementation clean and let the caller decide how to handle exceptions.

Syntax of throws

returnType methodName(parameters) throws ExceptionType1, ExceptionType2 {
    // method code
}

Example of Using throws

// Method that throws a checked exception
public static void readFile(String fileName) throws IOException {
    FileReader file = new FileReader(fileName);
    BufferedReader reader = new BufferedReader(file);
    String line = reader.readLine();
    System.out.println(line);
    reader.close();
}

// Main method that calls readFile and handles the exception
public static void main(String[] args) {
    try {
        readFile("example.txt");
    } catch (IOException e) {
        System.out.println("An error occurred: " + e.getMessage());
    }
}

Explanation:

  • throws IOException: The readFile method declares that it may throw an IOException. This informs the caller that it should handle this specific exception.
  • When calling readFile in the main method, it is wrapped inside a try-catch block. If an exception occurs, it’s caught and handled.

Checked vs. Unchecked Exceptions

  • Checked exceptions (such as IOException, SQLException) must either be caught or declared with throws in the method signature. The compiler forces this to ensure that all checked exceptions are handled.
  • Unchecked exceptions (like NullPointerException, ArithmeticException) do not require explicit handling or declaration with throws. These extend RuntimeException.

Multiple Exceptions with throws

If a method can throw multiple exceptions, you can list them all with throws:

public void performOperations() throws IOException, SQLException {
    // Code that may throw IOException or SQLException
}

Creating Methods with Custom Exceptions

You can also use throws with user-defined exceptions. Here’s an example:

// Custom checked exception
class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
}

public class ThrowsExample {
    public static void checkAge(int age) throws InvalidAgeException {
        if (age < 18) {
            throw new InvalidAgeException("Age must be 18 or older.");
        } else {
            System.out.println("Age is valid.");
        }
    }

    public static void main(String[] args) {
        try {
            checkAge(16);
        } catch (InvalidAgeException e) {
            System.out.println("Caught Exception: " + e.getMessage());
        }
    }
}

Key Points to Remember:

  • throws keyword declares the exceptions that a method can throw, allowing the caller to handle them.
  • It’s used only with checked exceptions, not with unchecked exceptions.
  • The throws keyword does not throw an exception itself; it only declares that the method may do so.
  • It promotes cleaner code by separating the handling of exceptions from the method that generates them.