• 记一下一道关于finally的题


     题目:

    public class Test{ 
        public int add(int a,int b){   
             try {
                 return a+b;      
             } 
            catch (Exception e) {  
                System.out.println("catch语句块");
             }
             finally{ 
                 System.out.println("finally语句块");
             }
             return 0;
        } 
         public static void main(String argv[]){ 
             Test test =new Test(); 
             System.out.println("和是:"+test.add(9, 34)); 
         }
    }

    结果是:

    finally语句块
    和是:43

    为什么呢?首先,这个字符串的相加,涉及变量,所以底层是通过StringBuilder来进行的,所以先进入test.add(9, 34)。

    然后,要个道理要知道,这是来自《The Java Tutorials》文档中的一段描述Finally关键字的话:

    上面说到,finally块总是会在try块结束后执行,来保证finally块一定会执行,哪怕是有无法预测的异常抛出。但确实这个finally模块不仅仅是在异常控制中有所作用,它允许编程者在代码运行return,continue或者是break语句之前进行些其他的工作,像cleanup某些资源的代码。

    但是!如果JVM(Java虚拟机)在执行try或者catch块的代码的时候退出了,那么finally块中的代码也就可能不会被执行到了,就像线程执行的时候被打断或者是直接被杀死这类的情况。

    总结一下,实验的结论就是:finally块中的语句总是会在控制转移语句(break、continue、return等)执行之前执行!除非是遇到JVM退出的情况,finally块中的内容才不会被执行。

    所以,这里在要执行try中的return之前,先去执行了finally中的打印语句,就有了这样的输出。

    再来看两个特殊的例子

    public abstract class Test {
        public static void main(String[] args) {
            System.out.println(beforeFinally());
        }
         
        public static int beforeFinally(){
            int a = 0;
            try{
                a = 1;
                return a;
            }finally{
                a = 2;
            }
        }
    }
    /**output:
    1
    */

    从结果上看,貌似`finally` 里的语句是在`return` 之后执行的,其实不然,实际上`finally` 里的语句是在在`return` 之前执行的。那么问题来了,既然是在之前执行,那为什么`a` 的值没有被覆盖了?


    实际过程是这样的:当程序执行到try{}语句中的return方法时,它会干这么一件事,将要返回的结果存储到一个临时栈中,然后程序不会立即返回,而是去执行finally{}中的程序, 在执行`a = 2`时,程序仅仅是覆盖了a的值,但不会去更新临时栈中的那个要返回的值 。执行完之后,就会通知主程序“finally的程序执行完毕,可以请求返回了”,这时,就会将临时栈中的值取出来返回。这下应该清楚了,要返回的值是保存至临时栈中的

    再来看一个例子,稍微改下上面的程序:

    public abstract class Test {
        public static void main(String[] args) {
            System.out.println(beforeFinally());
        }
         
        public static int beforeFinally(){
            int a = 0;
            try{
                a = 1;
                return a;
            }finally{
                a = 2;
                return a;
            }
        }
    }
    /**output:
    2
    */

    在这里,finally{}里也有一个return,那么在执行这个return时,就会更新临时栈中的值。同样,在执行完finally之后,就会通知主程序请求返回了,即将临时栈中的值取出来返回。故返回值是2。

  • 相关阅读:
    爬取笔趣阁小说(一念永恒)
    爬虫requests爬去网页乱码问题
    requests bs4 datetime re json
    添加背景音乐。c
    strip()
    爬虫学习中遇到的问题
    super的用法(带了解)
    user-agent
    输入n个字符串,用空格隔开。这些字符串中有重复出现的。现在统计每个字符串出现的次数,并找出出现次数最多的字符串。
    字节跳动小程序的一些坑
  • 原文地址:https://www.cnblogs.com/wangshen31/p/10483631.html
Copyright © 2020-2023  润新知