Regarding Final Rethrow

626 views Asked by At

I read in the documentation of Precise Rethrow that, http://www.theserverside.com/tutorial/OCPJP-Use-more-precise-rethrow-in-exceptions-Objective-Java-7

Basically, you can list specific exceptions in the throws clause of your method, even if they are not explicitly handled by a catch block if:

The try block actually throws that specific exception at some point in time.

The specific Exception isn't already handled at any point by a preceding catch block

The exception named in the throws clause of the method signature must be on the class hierarchy of at least one exception being handled and rethrown by a catch block (subtype or supertype)

Have a look at the code (attention on throws clause of main)

class OpenException extends Exception {}

class CloseException extends Exception {}

public class PRethrow
{
    public static void main(String args[]) throws OpenException, CloseException, java.io.IOException
    {
        boolean flag = true;
        try
        {
            if (flag)
            {
                throw new OpenException();
            }
            else
            {
                throw new CloseException();
            }
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            throw e;
        }
    } 
}

It is clearly mentioned in the first condition that, you can list a specific exception in throws clause if the try block actually throws that specific exception at some point in time.

In my code the try block never throws java.io.IOException, but still including it in throws clause produce no error.

why?

2

There are 2 answers

2
assylias On

The quote you mention is misleading:

  • If a checked exception may be thrown in your method body you must declare it in the throws clause of the method.
  • But you may add any exception to the throws clause of a method, whether it can actually be thrown or not.

For example this compiles:

public void m() throws IOException {}
1
M A On

I think you misunderstood the context in which the article is stating this condition. The article is saying that in Java 7, not declaring Exception in the throws clause is OK if the throws clause declares an exception that is actually thrown by the try block, namely OpenException and CloseException. In a sense, the compiler of Java 7 is now smart enough to know that only OpenException and CloseException can be thrown by the try block. So it no longer requires that the method declares throws Exception.

This has nothing to do with IOException and it doesn't change the fact that you can declare any exception to be thrown regardless of whether the exception can actually be thrown or not. The throws clause is just part of the method API.

The whole point of the condition stated in the article is that the following:

public static void main(String args[]) throws OpenException, CloseException, 
                                              java.io.IOException
{
    boolean flag = true;
    try
    {
        if (flag)
        {
            throw new OpenException();
        }
        else
        {
            throw new CloseException();
        }
    }
    catch (Exception e)
    {
        System.out.println(e.getMessage());
        throw e;       // this causes a compilation error before Java 7
    }
}

compiles in Java 7 but not in Java 6.