Venkata Raju
Venkata Raju

Reputation: 5217

Why do either of these rethrown exceptions create a compiler error?

Why does throw outerE; generate a compilation error? I know that throw e; should not generate a compiler error because of the precise rethrow feature.

They're the same Exception object, but one is scoped inside the catch block only and one is scoped outside the try-catch block.

Shouldn't neither of these generate a compiler error? Or, at least, both behave the same way?

static void preciseRethrowTest()
{
    Exception outerE;
    try
    {

    }
    catch (Exception e)
    {
        outerE = e;

        // Compilation error here. Unhandled exception type Exception
        // throw outerE; 

        throw e; // No compiler error
    }
}

I'm using Java 1.8.0_51. (Precise rethrow is introduced in Java 7)

Upvotes: 12

Views: 290

Answers (2)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279920

Your method has no throws declarations.

The compiler is now smart enough to determine that your try block cannot throw any checked exceptions. Therefore, any exceptions caught and bound to the Exception parameter in your catch block must be unchecked. Since they are unchecked, you can rethrow them at your leisure (and they won't require a throws declaration).

Here, you are attempting to reassign

outerE = e;
// Compilation error here. Unhandled exception type Exception
// throw outerE; 

and rethrow the exception through a different variable. The compiler doesn't go that far to figure out what the value in outerE is. It can be the exception in you caught or it can be something else. The compiler play it safe and prevents you from doing it.

Consider code like

if (Math.random() < 0.5) 
    outerE = e;
else 
    outerE = new IOException("nope");
throw outerE; 

There's no way for the compiler to know whether the Exception value stored in outerE is the unchecked exception you caught or some other, potentially checked, exception you assigned from somewhere else.

Upvotes: 6

durron597
durron597

Reputation: 32323

The problem is that the catch block cannot be reached by checked exceptions; the compiler is smart enough to realize this.

Consider this:

public class RethrowTest {
  static void preciseRethrowTest() {
    Exception outerE;
    try {
      throw new Exception();
    } catch (Exception e) {
      outerE = e;

      // Compilation error here. Unhandled exception type Exception
      // throw outerE;

      throw e; // Now a compiler error *is* generated.
    }
  }
}

This does throw a compiler error, because the code can be reached by a checked exception now.

Upvotes: 1

Related Questions