Demystifying ‘Throw’ and ‘Throws’ in Java Programming

JavaScript against the background of program code

Demystifying ‘Throw’ and ‘Throws’ in Java Programming

Throw

In Java, the ‘throw’ keyword is leveraged to manually induce an exception. When one method summons another (this could be the main method calling other methods or a separate method activating a different one), an exception object is then dispatched to the calling method. The moment a ‘throw’ statement is executed, the program execution halts straightaway. Any statements following the ‘throw’ are left unexecuted. ‘Throw’ can be utilized to hurl both checked and unchecked exceptions, all of which are subclasses of the Throwable class. Predominantly, ‘throw’ is employed in the creation and implementation of custom exceptions.

Illustrating the Use of ‘Throw’ in Java

Let’s dive into an illustrative example to get a better understanding of ‘throw’. This instance constructs a ‘validate’ method, which accepts an integer parameter. This numerical value is then viewed as a person’s age. If this ‘age’ is less than 18, a ArithmeticException is thrown via ‘throw’. If not, a message, “welcome to vote”, gets printed.

class Excep13 {
    void validate(int age) {
        if (age < 18) {
            throw new ArithmeticException("Not valid");
        } else {
            System.out.println("Welcome to vote");
        }
    }
}
class ExceptionHandling {
    public static void main(String args[]) {
        Excep13 obj = new Excep13();
        obj.validate(19); // For age greater than 18 example
        System.out.println("Rest of the code...");
    }
}

Throws

In Java, the ‘throws’ keyword plays a pivotal role in the handling of exceptions – specifically, checked exceptions. Unlike the ‘throw’ keyword, which actively induces an exception, ‘throws’ is utilized to declare that an exception might occur. This declaration happens in the signature of the method that might result in said exception.

An Election Scenario with ‘Throws’

Let’s take a real-world scenario to clarify. In an election, voters are required to be 18 or older. We want the system, by default, to raise an exception if an individual below this age tries to vote. In this setup, we leveraged an ArithmeticException, which is an unchecked exception. However, if a checked exception was used, the program wouldn’t compile.

To bypass this hurdle and ensure that the program does compile – and checked exceptions are dealt with during runtime – the ‘throws’ keyword is utilized. This prevents underage voting by enforcing age validation and allowing the possibility of a checked exception (declaration).

A Banking Scenario with ‘Throws’

Consider another example. When attempting to withdraw funds from a bank account, your balance becomes a crucial factor. If you try to withdraw more than your available balance, an exception should be triggered to prevent overdraft. If this exception fails to occur, you could potentially drain your account unwittingly, only realizing when you receive your bank statements.

In scenarios like this, the role of ‘throws’ comes to the forefront. A ‘throws’ declaration in the withdrawal method would notify the system about a potential overdraft exception. Leveraging ‘throws’ this way helps to combat unchecked spending and protect the account holder from unwelcome surprises.

void withdrawMoney() throws OverdraftException {
    // code
}

Exception Handling vs Exception Declaring

A key question revolves around when to handle an exception and when to declare it. The decision boils down to the specific use case. If a method can resolve an issue itself, then it makes sense for the method to handle the exception. However, if the issue lies outside the method’s means, then the problem should be passed back to the method’s caller – and this is where ‘throws’ comes into play.

For instance, if you attempt to make a deposit at your bank, but the bank’s computer system fails, the issue is on the bank’s end. The deposit method should handle the exception and attempt to rectify the issue. However, if the system failure affects your deposit transaction, you need to be informed that the deposit was unsuccessful. This notification happens via an exception thrown back to you.

void depositMoney() throws TransactionException {
    // code
}

An Illustrative Example of ‘Throws’

Consider the following example:

class ValidateAge {

    void checkAge(int age) throws IllegalArgumentException {

        if (age < 18)
            throw new IllegalArgumentException("Invalid age for voting");
        else
            System.out.println("Eligible to vote");

    }

}

class Election {

    public static void main(String args[]) throws IllegalArgumentException {

        ValidateAge obj = new ValidateAge();
        obj.checkAge(13); // For age less than 18 example
        System.out.println("Remaining code...");

    }

}

In this example, an IllegalArgumentException (a checked exception) is thrown when the age is less than 18.

Program code on a computer screen, close-up view

Which Exception Should We Declare?

Primarily, only checked exceptions should be declared. This is because unchecked exceptions and errors are generally under your control. For instance, if an OutOfMemoryError occurs, there is little a programmer can do as it’s beyond their control. However, declaring an unchecked exception will not result in a compilation error.

The Power of ‘Throws’

‘Throws’ facilitates the propagation of checked exceptions. This means that an exception can be effectively forwarded in the call stack. Here is an example:

class Transaction {

    void process() throws IOException {
        throw new IOException("Transaction error"); // checked exception
    }

    void executeTransaction() throws IOException {
        process();
    }

    void initiateTransaction() {
        try {
            executeTransaction();
        } catch (IOException exp) {
            System.out.println("Exception handled");
        }
    }

    public static void main(String args[]) {
        Transaction obj = new Transaction();
        obj.initiateTransaction();
        System.out.println("Normal flow...");
    }
}

In this code, the checked IOException is propagated up the call stack. This allows for effective management of the exception.

Conclusion 

In Java exception handling, understanding and aptly using ‘throw’ and ‘throws’ are integral components of building robust applications. While ‘throw’ is employed to explicitly induce exceptions, ‘throws’ declares the potential for exceptions, notifying the compiler and end-users alike. Through judicious use of these keywords, not only can we keep our Java programs resilient in the face of runtime issues, but also enhance their overall readability and maintainability, thereby ensuring an efficient and seamless coding experience.If you’re aiming to enhance your Java programming expertise, it’s advisable to deepen your understanding of Checked versus Unchecked Exceptions.