javamethodssignatureoverridingthrows

Java overriding throws clause


I'm learning for OCJP exam by reading the book written by S G Ganesh and Tushar Sharma. At page 346 there is a text that says:

What if you try changing the throws clause? There are many ways to change the throws clause in the overriding method, including the following:
a. Not providing any throws clause.
b. Listing more general checked exceptions to throw.
c. Listing more checked exceptions in addition to the given checked exception(s) in the base method.
If you attempt any of these three cases, you’ll get a compiler error. For example, try not providing the throws clause in the readIntFromFile() method in the class that implements the IntReader interface.

public int readIntFromFile() {
    Scanner consoleScanner = new Scanner(new File("integer.txt"));
    return consoleScanner.nextInt();
}

You’ll get this compiler error: “unreported exception FileNotFoundException; must be caught or declared to be thrown.”
To summarize, the base class method’s throws clause is a contract that it provides to the caller of that method:
it says that the caller should handle the listed exceptions or declare those exceptions in its throws clause. When overriding the base method, the derived method should also adhere to that contract. The caller of the base method is prepared to handle only the exceptions listed in the base method, so the overriding method cannot throw more general or other than the listed checked exceptions.
However, note that this discussion that the derived class method’s throws clause should follow the contract for the base method’s throws clause is limited to checked exceptions. Unchecked exceptions can still be added or removed from the contract when compared to the base class method’s throws clause. For example, consider the following:

public int readIntFromFile() throws IOException, NoSuchElementException {
    Scanner consoleScanner = new Scanner(new File("integer.txt"));
    return consoleScanner.nextInt();
}

This is an acceptable throws clause since NoSuchElementException can get thrown from the readIntFromFile() method. This exception is an unchecked exception, and it gets thrown when the nextInt() method could not read an integer from the file. This is a common situation, for example, if you have an empty file named integer.txt; an attempt to read an integer from this file will result in this exception.

I'm a little bit concerned about the point "a.". It says that if you don't provide any throws clause the code won't compile. But when I was learning for OCA, I remember I read that you can provide the same throws clause, a more specific Exception or no throws clause at all and the code will still compile and these are available only for Checked Exceptions. I've tried to do some tests but I can't get “unreported exception FileNotFoundException; must be caught or declared to be thrown.”. I remember I saw it but I don't know in which conditions.


Solution

  • As Manouti said, the book is wrong. You can definitely have more precise or no exception, but you cannot have a more general one :

    interface A {
        void meth() throws IOException;
    }
    
    class B implements A {
        @Override
        void meth() throws FileNotFoundException { } // compiles fine
    }
    
    class C implements A  {
        @Override
        void meth() { } // compiles fine
    }
    
    class D implements A  {
        @Override
        void meth() throws Exception { } // compile error
    }