三好街做网站公司,企业商城网站开发建设,做网站需要平台,晨星wordpress 主题网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行#xff1f;很多人都说不是#xff0c;当然他们的回答是正确的#xff0c;经过我试验#xff0c;至少有两种情况下finally语句是不会被执行的#xff1a; try语句没有被执行到… 网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行很多人都说不是当然他们的回答是正确的经过我试验至少有两种情况下finally语句是不会被执行的 try语句没有被执行到如在try语句之前就返回了这样finally语句就不会执行这也说明了finally语句被执行的必要而非充分条件是相应的try语句一定被执行到。在try块中有System.exit(0);这样的语句System.exit(0);是终止Java虚拟机JVM的连JVM都停止了所有都结束了当然finally语句也不会被执行到。 当然还有很多人探讨Finally语句的执行与return的关系颇为让人迷惑不知道finally语句是在try的return之前执行还是之后执行我也是一头雾水我觉得他们的说法都不正确我觉得应该是finally语句是在try的return语句执行之后return返回之前执行。这样的说法有点矛盾也许是我表述不太清楚下面我给出自己试验的一些结果和示例进行佐证有什么问题欢迎大家提出来。 1、finally语句在return语句执行之后return返回之前执行的。 public class FinallyTest1 {public static void main(String[] args) {System.out.println(test1());}public static int test1() {int b 20;try {System.out.println(try block);return b 80; }catch (Exception e) {System.out.println(catch block);}finally {System.out.println(finally block);if (b 25) {System.out.println(b25, b b);}}return b;}}运行结果 try block
finally block
b25, b 100
100 说明return语句已经执行了再去执行finally语句不过并没有直接返回而是等finally语句执行完了再返回结果。
如果觉得这个例子还不足以说明这个情况的话下面再加个例子加强证明结论
public class FinallyTest1 {public static void main(String[] args) {System.out.println(test11());}public static String test11() {try {System.out.println(try block);return test12();} finally {System.out.println(finally block);}}public static String test12() {System.out.println(return statement);return after return;}}运行结果 try block
return statement
finally block
after return 说明try中的return语句先执行了但并没有立即返回等到finally执行结束后再返回。
这里大家可能会想如果finally里也有return语句那么是不是就直接返回了try中的return就不能返回了看下面。 2、finally块中的return语句会覆盖try块中的return返回。
public class FinallyTest2 {public static void main(String[] args) {System.out.println(test2());}public static int test2() {int b 20;try {System.out.println(try block);return b 80;} catch (Exception e) {System.out.println(catch block);} finally {System.out.println(finally block);if (b 25) {System.out.println(b25, b b);}return 200;}// return b;}}运行结果 try block
finally block
b25, b 100
200 这说明finally里的return直接返回了就不管try中是否还有返回语句这里还有个小细节需要注意finally里加上return过后finally外面的return b就变成不可到达语句了也就是永远不能被执行到所以需要注释掉否则编译器报错。
这里大家可能又想如果finally里没有return语句但修改了b的值那么try中return返回的是修改后的值还是原值看下面。 3、如果finally语句中没有return语句覆盖返回值那么原来的返回值可能因为finally里的修改而改变也可能不变。
测试用例1public class FinallyTest3 {public static void main(String[] args) {System.out.println(test3());}public static int test3() {int b 20;try {System.out.println(try block);return b 80;} catch (Exception e) {System.out.println(catch block);} finally {System.out.println(finally block);if (b 25) {System.out.println(b25, b b);}b 150;}return 2000;}}运行结果 try block
finally block
b25, b 100
100 测试用例2
import java.util.*;public class FinallyTest6
{public static void main(String[] args) {System.out.println(getMap().get(KEY).toString());}public static MapString, String getMap() {MapString, String map new HashMapString, String();map.put(KEY, INIT);try {map.put(KEY, TRY);return map;}catch (Exception e) {map.put(KEY, CATCH);}finally {map.put(KEY, FINALLY);map null;}return map;}
}运行结果 FINALLY 为什么测试用例1中finally里的b 150;并没有起到作用而测试用例2中finally的map.put(KEY, FINALLY);起了作用而map null;却没起作用呢这就是Java到底是传值还是传址的问题了具体请看精选30道Java笔试题解答里面有详细的解答简单来说就是finally是在return语句执行之后返回之前执行的此时并没有返回运算后的值而是先把要返回的值保存起来不管finally中的代码怎么样返回的值都不会改变仍然是之前保存的值所以函数返回值是在finally执行前就已经确定了。Java中只有传值没有传址这也是为什么map null这句不起作用。这同时也说明了返回语句是try中的return语句而不是 finally外面的return b;这句不相信的话可以试下将return b;改为return 294对原来的结果没有一点影响。
这里大家可能又要想是不是每次返回的一定是try中的return语句呢那么finally外的return b不是一点作用没吗请看下面。 4、try块里的return语句在异常的情况下不会被执行这样具体返回哪个看情况。
public class FinallyTest4 {public static void main(String[] args) {System.out.println(test4());}public static int test4() {int b 20;try {System.out.println(try block);b b / 0;return b 80;} catch (Exception e) {b 15;System.out.println(catch block);} finally {System.out.println(finally block);if (b 25) {System.out.println(b25, b b);}b 50;}return 204;}}运行结果 try block
catch block
finally block
b25, b 35
85这里因 为在return之前发生了除0异常所以try中的return不会被执行到而是接着执行捕获异常的catch 语句和最终的finally语句此时两者对b的修改都影响了最终的返回值这时return b;就起到作用了。当然如果你这里将return b改为return 300什么的最后返回的就是300这毋庸置疑。 这里大家可能又有疑问如果catch中有return语句呢当然只有在异常的情况下才有可能会执行那么是在finally之前就返回吗看下面。 5、当发生异常后catch中的return执行情况与未发生异常时try中return的执行情况完全一样。
public class FinallyTest5 {public static void main(String[] args) {System.out.println(test5());}public static int test5() {int b 20;try {System.out.println(try block);b b /0;return b 80;} catch (Exception e) {System.out.println(catch block);return b 15;} finally {System.out.println(finally block);if (b 25) {System.out.println(b25, b b);}b 50;}//return b;}}运行结果 try block
catch block
finally block
b25, b 35
35 说明了发生异常后catch中的return语句先执行确定了返回值后再去执行finally块执行完了catch再返回finally里对b的改变对返回值无影响原因同前面一样也就是说情况与try中的return语句执行完全一样。 总结 1、不管有木有出现异常finally块中代码都会执行
2、当try和catch中有return时finally仍然会执行
3、finally是在return语句执行之后返回之前执行的此时并没有返回运算后的值而是先把要返回的值保存起来不管finally中的代码怎么样返回的值都不会改变仍然是之前保存的值所以函数返回值是在finally执行前就已经确定了
4、finally中如果包含return那么程序将在这里返回而不是try或catch中的return返回返回值就不是try或catch中保存的返回值了。 注 1、finally修改的基本类型是不影响返回结果的。传值的 2、修改list ,map,自定义类等引用类型时是影响返回结果的。传址的对象也是传址的但是date类型经过测试是不影响的。有点奇怪。