Summary: | Compiler inconsistent with javac when code returns from inside a finally {} block | ||
---|---|---|---|
Product: | [Eclipse Project] JDT | Reporter: | Andrew McCullough <mccull1> |
Component: | Core | Assignee: | Philipe Mulet <philippe_mulet> |
Status: | RESOLVED WORKSFORME | QA Contact: | |
Severity: | normal | ||
Priority: | P3 | CC: | gust |
Version: | 2.0 | ||
Target Milestone: | 2.1 M2 | ||
Hardware: | PC | ||
OS: | other | ||
Whiteboard: |
Description
Andrew McCullough
2002-08-14 15:24:33 EDT
Ooops, there should also be a call to t.doSomething() in there. I was playing with the test case, but the other points remain the same. The correct test case is: package com.test; public class FinallyExceptionTest { public static void main(String[] arguments) { try { FinallyExceptionTest t = new FinallyExceptionTest(); t.doSomething(); System.out.println("I shouldn't get here"); } catch (Exception e) { e.printStackTrace(); } } public void doSomething() { try { throw new Exception("Exception"); } finally { return; } } } Finally block have to be run during exception handling, and may cause abrupt termination of method. This is the language specified behavior. Technically, a finally block is not much different from a catch block which is ensured to be both on the exception and normal termination execution path. In cases, this can become convenient to replace an exception with another one. try { throw new A(); } finally { throw new B(); } Returning finally blocks can easily become counter-intuitive: try { return 1; } finally { return 2; // 2 will be returned } A good programming style is probably to avoid returning directly from whithin finally blocks. Now for the compiler behavior, I would say our behavior is the proper one, in the sense it matches the runtime silent absorption of the exception. Will investigate some more. This behavior as I observed in JDK 1.4 also shows the problem. /** * @author Sanjay Madhavan * * Test case to show a problem/feature? with exception handling and * method signatures when a finally block is specified. * This behavior is observed in Eclipse Version: 2.0 Build id: 200208201620 * * The Sun java compiler in JDK version "1.4.0_01" correctly flags the * testExceptionWronglyCompiles method as incorrect. */ public class TestException { /* * This method will compile. This is correct behavior */ public String testExceptionCorrect() throws Exception { throw new Exception(); } /* * This method will not compile. This is correct behavior */ public String testExceptionWillNotCompile() { if (true) throw new Exception(); return "bogus"; } /* * This method will compile. This to me is INCORRECT behavior. */ public String testExceptionWronglyCompiles() { try { throw new Exception(); } catch (Exception me) { throw me; } finally { // the return within the finally seems to confuse the compiler return "bogus"; } } public static void main(String[] args) { TestException test = new TestException(); System.out.println( "testExceptionWronglyCompiles returned: " + test.testExceptionWronglyCompiles()); } } Sanjay - What makes you think our compiler is wrong ? When running the offending method, do you get any uncaught exception stack trace ? No, because the exception is never surfaced beyond the finally block. Javac doesn't notice it, we do. Just for the record (I can't speak for Sanjay), but I actually think Eclipse's interepretation is more "technically correct". I just reported the bug to note the inconsistency as people get upset when something compiles in Eclipse and not with javac/jikes or vice versa. I am a little dissapointed this can happen at all according to the JLS. Throughout the language, Java is very careful to ensure exceptions are handled through some purposeful action (catch/throw), and in this case you can "accidentally" not handle an exception. Some well-meaning programmer on my project was trying to fix a "JTest" error (static code analysis) which complained there were too many return statements in the method. Instead of improving the code, though, it caused a very subtle bug with the exceptional conditions. Of course, once I noticed the return in the finally... -Andrew Closing, behaving as expected. *** Bug 46421 has been marked as a duplicate of this bug. *** We added a warning to signal that the finally block is not completing normally. |