3

Is this Java code legal? Apparently it gets different results on different compilers.

foo throws Exception without declaring it.

If the code in the try block does not declare any exceptions thrown, then we know that any Exception reaching the catch block is RuntimeException, so actually, this is OK.

But that seems to require a deep static code analysis, while a simple syntactic reading of this method says that it is illegal.

Can you refer me to an article or section of the language spec?

public void foo() {// no  throws clause
    try {
        // Lines of code
    } catch (Exception e) {
        throw e;
    }  
}
Joshua Fox
  • 18,704
  • 23
  • 87
  • 147
  • I hope that this is acceptable. I tried it on Programming StackExchange and it was closed with the statement that it is more appropriate for StackOverflow. – Joshua Fox Apr 03 '18 at 09:45
  • 3
    "Apparently it gets different results on different compilers." Examples of that would improve the question, IMO. (But apart from that, it seems like a perfectly good question. I suspect that section 11.2.2 of the JLS is relevant here, but I'm finding it difficult to understand today.) – Jon Skeet Apr 03 '18 at 09:47
  • This might help https://stackoverflow.com/questions/4519557/is-there-a-way-to-throw-an-exception-without-adding-the-throws-declaration/4519576 – Tahir Hussain Mir Apr 03 '18 at 09:55
  • This looks relevant: https://stackoverflow.com/questions/12051791/is-there-ever-a-reason-to-not-use-the-final-keyword-when-catching-an-exception/12051907#12051907 . Compiler allows rethrowing Exception, if it knows it has to be RuntimeException or an exception declared to throw. – user158037 Apr 03 '18 at 10:01
  • @JonSkeet Unfortunately the only source I have for it not compiling is a comment from @ gnat on the since-deleted Programming StackExchange question: "this code doesn't look legal to me. When I tried it it failed to compile with "Unhandled exception" error. I am using javac 1.8.0_161 in Eclipse Oxygen.2 and it does compile – Joshua Fox Apr 03 '18 at 10:02
  • @user158037 that looks good. I am not finding a discussion of "Compiler allows rethrowing Exception, if it knows it has to be Run timeException or an exception declared to throw" there. But as @ jonskeet says, sec 11.2.2 that is hard to understand. – Joshua Fox Apr 03 '18 at 10:05
  • @TahirHussainMir Thank you. That is more about how to "trick" the compiler whereas my question is what is apparently a supported, but obscure, syntactic feature. – Joshua Fox Apr 03 '18 at 10:05
  • Java code is legal, though its not recommended to throw parent "Exception", Exception also is parent of RuntimeException for which we dont need to declare in method , but if there would be checked exception then its must to declare in method. – Afgan Apr 03 '18 at 10:05

1 Answers1

3

See §11.2 Compile-Time Checking of Exceptions:

For each checked exception which is a possible result, the throws clause for the method or constructor must mention the class of that exception or one of the superclasses of the class of that exception (§11.2.3).

Further sections go in detail about exception analysis of expressions and statements.

If you try it with the code:

    try {
        // Lines of code
    } catch (Exception e) {
        throw e;
    }

it does not effectively throw any checked exceptions. It did not give me any compiler error in Eclipse.

However if you try something like:

    try {
        new URL("https://www.stackoverflow.com");
    } catch (Exception e) {
        throw e;
    }

it can throw a checked exception and it (or its superclass) must be mentioned in throws. This gives me an "Unhandled exception type MalformedURLException" compiler error in Eclipse.

lexicore
  • 42,748
  • 17
  • 132
  • 221
  • Looks good. This hinges on the definition of "possible result." In this case, a checked exception is indeed not "possible". Can you tell me more or find an article about the apparent difference between simple local typechecking vs what looks like a deeper static analysis? – Joshua Fox Apr 03 '18 at 10:08
  • @JoshuaFox I think this is an interpretation of "The `try` block can throw `E`" by the compiler. It gets really interesting when the `try` block can throw some unchecked exception. I don't get a compilation error in Eclipse in this case. – lexicore Apr 03 '18 at 10:12
  • I would add that this `catch` statement is valid because it will only catch every unchecked exception since nothing in the `try` statement can throw a checked exception. So the compiler understand only `RuntimeException` can happen. This seems logic since a `catch` for a specific checked exception that is never thrown will not compile. Interesting behavior, not expected to be honest ! – AxelH Apr 03 '18 at 10:49