zoukankan      html  css  js  c++  java
  • Java基础知识强化之IO流笔记06:有return的情况下try catch finally的执行顺序

    1. 给出结论:

    (1)不管有木有出现异常,finally块中代码都会执行
    (2)当try和catch中有return时,finally仍然会执行
    (3)finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的
    (4)finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值

    举例:

    情况1:try{} catch(){}finally{} return;
              显然程序按顺序执行。


    情况2:try{ return; }catch(){} finally{} return;
              程序执行try块中return之前(包括return语句中的表达式运算)代码;
              再执行finally块,最后执行try中return;
              finally块之后的语句return,因为程序在try中已经return所以不再执行。


    情况3:try{ } catch(){return;} finally{} return;
              程序先执行try,如果遇到异常执行catch块,
              有异常:则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
                         最后执行catch块中return. finally之后也就是4处的代码不再执行。
              无异常:执行完try再finally再return.


    情况4:try{ return; }catch(){} finally{return;}
              程序执行try块中return之前(包括return语句中的表达式运算)代码;
              再执行finally块,因为finally块中有return所以提前退出。


    情况5:try{} catch(){return;}finally{return;}
              程序执行catch块中return之前(包括return语句中的表达式运算)代码;
              再执行finally块,因为finally块中有return所以提前退出。


    情况6:try{ return;}catch(){return;} finally{return;}
              程序执行try块中return之前(包括return语句中的表达式运算)代码;
              有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
                           则再执行finally块,因为finally块中有return所以提前退出。
              无异常:则再执行finally块,因为finally块中有return所以提前退出。


    最终结论

     任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,编译器把finally中的return实现为一个warning

    2. 至少有两种情况下finally语句是不会被执行的:

    (1)try语句没有被执行到,如在try语句之前return就返回了这样finally语句就不会执行,这也说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。

    (2)在try块中有System.exit(0);这样的语句,System.exit(0);是终止Java虚拟机JVM的,连JVM都停止了,所有都结束了,当然finally语句也不会被执行到。

    -->1.案例如下:

     1 package com.himi.finallydemo;
     2 
     3 public class FinallyDemo2 {
     4 
     5     public static void main(String[] args) {
     6         System.out.println(getInt());
     7 
     8     }
     9 
    10     public static int getInt() {
    11         int a = 10;
    12         try {
    13             System.exit(0);
    14             System.out.println(a / 0);
    15             a = 20;
    16 
    17         } catch (ArithmeticException e) {
    18             a = 30;
    19             // return a;
    20         } finally {
    21             a = 40;
    22         }
    23 
    24         return a;
    25     }
    26 
    27 }

    运行效果如下:

    上面的getInt()方法中,先执行int a = 10;然后再执行try语句,发现开始就是System.exit(0),这样虚拟机jvm直接退出,当然也不会印出任何信息

    -->2. 案例如下:

     1 package com.himi.finallydemo;
     2 
     3 public class FinallyDemo2 {
     4 
     5     public static void main(String[] args) {
     6         System.out.println(getInt());
     7 
     8     }
     9 
    10     public static int getInt() {
    11         int a = 10;
    12         try {
    13             System.out.println(a / 0);//执行完,直接跳转到第17行
    14             System.exit(0);
    15             a = 20;
    16 
    17         } catch (ArithmeticException e) {
    18             a = 30;
    19             // return a;
    20         } finally {
    21             a = 40;
    22         }
    23 
    24         return a;
    25     }
    26 
    27 }

    运行如下效果:

    这里在try语句中执行System.out.println(a / 0),系统会马上捕获到异常直接执行catch语句,然后执行finally语句,最后return a

    (此时a是40)

    -->3.案例:

     1 package com.himi.finallydemo;
     2 
     3 public class FinallyDemo2 {
     4 
     5     public static void main(String[] args) {
     6         System.out.println(getInt());
     7 
     8     }
     9 
    10     public static int getInt() {
    11         int a = 10;
    12         try {
    13             System.out.println(a / 0);
    14             System.exit(0);
    15             a = 20;
    16 
    17         } catch (ArithmeticException e) {
    18             a = 30;
    19             return a;
    20             /*
    21              * return a在程序执行到这一步的时候,这里不是return a而是return 30;这个返回路径就形成了。
    22              * 但是呢,它发现后面还有finally,所以继续执行fianlly的内容,a=40
    23              * 再次回到以前的返回路径,继续走return 30;
    24              */
    25         } finally {
    26             a = 40;
    27             //return 40;//如果这样结果就是40
    28         }
    29 
    30         return a;
    31     }
    32 
    33 }

    运行效果如下:

  • 相关阅读:
    使用PyDNS查询
    C#结构体
    使用CreateProcess函数运行其他程序
    运算符重载
    C#学习抽象类和方法
    sed命令使用
    Python For Delphi 示例
    建立Socket
    使用 lambda 函数
    C#接口实现
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4844883.html
Copyright © 2011-2022 走看看