PsyAp
PsyAp

Reputation: 323

Why does the compiler allow throws when the method will never throw the Exception

I am wondering why the java compiler allows throws in the method declaration when the method will never throw the Exception. Because "throws" is a way of handling the exception (telling the caller to handle it).

Since there are two ways of handling exception (throws & try/catch). In a try/catch, it doesn't allow the catch of an exception not thrown in the try block but it allows a throws in a method that does may not throw the exception.

private static void methodA() {
    try {
        // Do something
        // No IO operation here
    } catch (IOException ex) {  //This line does not compile because
                              //exception is never thrown from try
        // Handle   
    }
}

private static void methodB() throws IOException { //Why does this //compile when excetion is never thrown in function body
    //Do Something 
    //No IO operation
}

Upvotes: 22

Views: 4567

Answers (4)

Harsimran17
Harsimran17

Reputation: 9

  1. The methodB throws IOException, so the method calling methodB is responsible for catching the exception which will be thrown by methodB. Try calling methodB from other methods, it will ask you to catch it or re-throw the IOException. Somewhere you will have to catch the IOException in the chain (in try/catch block). So you wont get compile time error.

    private void sampleMethod(){ try { methodB(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

  2. try/catch in methodA admittedly swallows the exception, that means methodA is responsible for catching the exception in try/catch block. "Every statement in any java program must be reachable i.e every statement must be executable at least once" So, you will get compiler error as your try block doesn't have any code to cause IOException.

Upvotes: -1

Eran
Eran

Reputation: 393781

The throws clause is part of the method's contract. It requires the caller of the method to behave as if the specified exception may be thrown by the method (i.e. either catch the exception or declare their own throws clause).

It's possible that the initial version of a method does not throw the exception specified in the throws clause, but a future version can throw it without breaking the API (i.e. any existing code that calls the method will still pass compilation).

The opposite it also possible. If the method used to throw the exception specified in the throws clause, but a future version of it doesn't throw it anymore, you should keep the throws clause in order not to break existing code that uses your method.

First example:

Suppose you have this code which uses methodB:

private static void methodA() {
    methodB(); // doesn't have throws IOException clause yet
}

If later you want to change methodB to throw IOException, methodA will stop passing compilation.

Second example:

Suppose you have this code which uses methodB:

private static void methodA() {
    try {
        methodB(); // throws IOException
    }
    catch (IOException ex) {

    }
}

If you remove the throws clause from a future version of methodB, methodA won't pass compilation anymore.

This example is not very interesting when methodA is private, because it can only be used locally (within the same class, where it's easy to modify all the methods that call it).

However, if it becomes public, you don't know who uses (or will use) your method, so you have no control of all the code that may break as a result of adding or removing the throws clause.

And if it's an instance method, there's another reason for allowing the throws clause even if you don't throw the exception - the method can be overridden, and the overriding method may throw the exception even if the base class implementation does not.

Upvotes: 28

noname
noname

Reputation: 237

Keyword throws tells programmer that there could be an IOException happening in the method. Now if you didn't specify try/catch it means that when exception is thrown program will stop working, while in try/catch you handle it by doing something else if thrown exception.

Use throws for readability and specifying the possibility of exception and use try/catch to tell program what to do in case of exception.

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691665

Because the signature defines the contract of the method. Even if the method doesn't throw an IOException now, maybe it will in the future, and you want to prepare for that possibility.

Suppose you just provide a dummy implementation for the method for now, but you know that, later, the actual implementation will potentially throw an IOException. If the compiler prevented you from adding this throws clause, you would be forced to rework all the calls (recursively) to that method once you provide the actual implementation of the method.

Upvotes: 8

Related Questions