考虑到这段代码,我能绝对确定finally块总是执行的吗,不管something()是什么?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("I don't know if this will get printed out");
}

当前回答

示例代码:

public static void main(String[] args) {
    System.out.println(Test.test());
}

public static int test() {
    try {
        return 0;
    }
    finally {
        System.out.println("something is printed");
    }
}

输出:

something is printed. 
0

其他回答

示例代码:

public static void main(String[] args) {
    System.out.println(Test.test());
}

public static int test() {
    try {
        return 0;
    }
    finally {
        System.out.println("something is printed");
    }
}

输出:

something is printed. 
0

因为除非调用System.exit()(否则线程崩溃),否则将始终调用finally块。

我对不同论坛上提供的所有答案感到非常困惑,最终决定编码并查看。输出为:

即使try-and-catch块中有返回,也将执行finally。

try {  
  System.out.println("try"); 
  return;
  //int  i =5/0;
  //System.exit(0 ) ;
} catch (Exception e) {   
  System.out.println("catch");
  return;
  //int  i =5/0;
  //System.exit(0 ) ;
} finally {  
   System.out.println("Print me FINALLY");
}

输出

尝试最后打印我

如果返回被上述代码中try-and-catch块中的System.exit(0)替换,并且由于任何原因,在它之前发生了异常。

是的,总是执行finally块。大多数开发人员使用此块来关闭数据库连接、resultset对象、语句对象,还使用到java休眠来回滚事务。

是的,因为没有控制语句可以阻止finally被执行。

下面是一个参考示例,其中将执行所有代码块:

| x | Current result | Code 
|---|----------------|------ - - -
|   |                |     
|   |                | public static int finallyTest() {
| 3 |                |     int x = 3;
|   |                |     try {
|   |                |        try {
| 4 |                |             x++;
| 4 | return 4       |             return x;
|   |                |         } finally {
| 3 |                |             x--;
| 3 | throw          |             throw new RuntimeException("Ahh!");
|   |                |         }
|   |                |     } catch (RuntimeException e) {
| 4 | return 4       |         return ++x;
|   |                |     } finally {
| 3 |                |         x--;
|   |                |     }
|   |                | }
|   |                |
|---|----------------|------ - - -
|   | Result: 4      |

在下面的变体中,返回x;将跳过。结果仍然是4:

public static int finallyTest() {
    int x = 3;
    try {
        try {
            x++;
            if (true) throw new RuntimeException("Ahh!");
            return x; // skipped
        } finally {
            x--;
        }
    } catch (RuntimeException e) {
        return ++x;
    } finally {
        x--;
    }
}

当然,引用可以跟踪其状态。此示例返回值为4的引用:

static class IntRef { public int value; }
public static IntRef finallyTest() {
    IntRef x = new IntRef();
    x.value = 3;
    try {
        return x;
    } finally {
        x.value++; // will be tracked even after return
    }
}