Returning from a finally block in Java

前端 未结 6 1992
醉梦人生
醉梦人生 2020-11-22 11:02

I was surprised recently to find that it\'s possible to have a return statement in a finally block in Java.

It seems like lots of people think it\'s a bad thing to d

6条回答
  •  深忆病人
    2020-11-22 11:43

    A simple Groovy Test:

    public class Instance {
    
      List runningThreads = new ArrayList()
    
      void test(boolean returnInFinally) {
    
        println "\ntest(returnInFinally: $returnInFinally)"
        println "--------------------------------------------------------------------------"
        println "before execute"
        String result = execute(returnInFinally, false)
        println "after execute -> result: " + result
        println "--------------------------------------------------------------------------"
    
        println "before execute"
        try {
          result = execute(returnInFinally, true)
          println "after execute -> result: " + result
        } catch (Exception ex) {
          println "execute threw exception: " + ex.getMessage()
        }  
        println "--------------------------------------------------------------------------\n"
    
      }
    
      String execute(boolean returnInFinally, boolean throwError) {
          String thread = Thread.currentThread().getName()
          println "...execute(returnInFinally: $returnInFinally, throwError: $throwError) - thread: $thread"
          runningThreads.add(thread)
          try {
            if (throwError) {
              println "...error in execute, throw exception"
              throw new Exception("as you liked :-)")
            }
            println "...return 'OK' from execute"
            return "OK"
          } finally {
            println "...pass finally block"
            if (returnInFinally) return "return value from FINALLY ^^"
            // runningThreads.remove(thread)
          }
      }
    }
    
    Instance instance = new Instance()
    instance.test(false)
    instance.test(true)
    

    Output:

    test(returnInFinally: false)
    -----------------------------------------------------------------------------
    before execute
    ...execute(returnInFinally: false, throwError: false) - thread: Thread-116
    ...return 'OK' from execute
    ...pass finally block
    after execute -> result: OK
    -----------------------------------------------------------------------------
    before execute
    ...execute(returnInFinally: false, throwError: true) - thread: Thread-116
    ...error in execute, throw exception
    ...pass finally block
    execute threw exception: as you liked :-)
    -----------------------------------------------------------------------------
    
    
    test(returnInFinally: true)
    -----------------------------------------------------------------------------
    before execute
    ...execute(returnInFinally: true, throwError: false) - thread: Thread-116
    ...return 'OK' from execute
    ...pass finally block
    after execute -> result: return value from FINALLY ^^
    -----------------------------------------------------------------------------
    before execute
    ...execute(returnInFinally: true, throwError: true) - thread: Thread-116
    ...error in execute, throw exception
    ...pass finally block
    after execute -> result: return value from FINALLY ^^
    -----------------------------------------------------------------------------
    

    Question:

    One interesting point for me was to see how Groovy deals with implicit returns. In Groovy it is possible to "return" from a method simply leaving a value at the end (without return). What do you think happens, if you uncomment the runningThreads.remove(..) line in the finally statement - will this overwrite the regular return value ("OK") and cover the exception?!

提交回复
热议问题