try catch finally语句块中存在return语句时的运行流程

7 篇文章 0 订阅

题目:下面代码运行结果是() 

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)); 
     }
}

选项:

A、 catch语句块             B、编译异常          C、finally语句块        D、和是:43
  和是:43                                         和是:43                finally语句块

对于运行结果不理解的同学耐心看看接下来这两段代码,就会对try catch finally语句块存在return语句时的运行流程豁然开朗。

Code one:

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”里的语句是在try语句块“return”之后执行的,其实不然,实际上“finally” 里的语句是在“return” 之前执行的。那么问题来了,既然是在之前执行,那为什么`a` 的值没有被覆盖了?

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

Code two:

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
*/

跟Code one不同的是现在finally语句块中也有return语句,那么在执行这个return时,就会更新临时栈中的值。同样,在执行完finally之后,就会通知主程序请求返回了,即将临时栈中的值取出来返回。故返回值是2。

现在回过头来看看一开始的那段代码:

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)); 
     }
}

过程剖析:① 第16行代码因为字符串拼接是一个整体,所以必须先获取add方法的运算结果才能输出。故排除D选项。②try 和 catch两语句块同时存在时,如果try中有return语句,那么后面try catch finally语句块之外的return语句就不起作用了,编译器也不会报“Unreachable code”错误。大家可以打开编译器试试。故排除B选项。③ try块没有产生任何运行时异常,因此排除A选项。④ finally语句块中的语句先于return语句运行,因此控制台输出“finally语句块”,然后执行return语句返回运算结果。最后回到主程序,字符串拼接完成输出“和是43”。故正确答案为C。

关于我

微信公众号:Guevara的笔记,技术菜鸟记录技术学习过程。

微信公众号:Guevara的笔记

 

 

在 Java try-catch-finally 语句用于捕获和处理异常。它的基本语法如下: ```java try { // 可能会抛出异常的代码 } catch (ExceptionType1 e1) { // 处理异常类型1的代码 } catch (ExceptionType2 e2) { // 处理异常类型2的代码 } finally { // 无论是否发生异常,都会执行的代码 } ``` 在 try ,你可以放置可能会抛出异常的代码。如果在执行 try 的代码发生了异常,那么就会跳到相应的 catch 进行异常处理。catch 可以有多个,每个 catch 用于捕获不同类型的异常,并提供相应的处理逻辑。catch 的参数 e1、e2 是异常对象,你可以使用它们来获取有关异常的信息。 无论是否发生异常,finally 的代码都会被执行。finally 通常用于释放资源或执行清理操作,确保在任何情况下都会执行。 如果在 try 发生了异常,并且没有相应的 catch 来处理该异常,那么该异常将被传递给上层调用栈,直到找到合适的 catch 进行处理,或者如果没有找到任何 catch ,则程序将终止。 以下是一个简单的示例: ```java try { int result = divide(10, 0); System.out.println("结果:" + result); } catch (ArithmeticException e) { System.out.println("除数不能为零!"); } finally { System.out.println("finally 的代码"); } public static int divide(int dividend, int divisor) { return dividend / divisor; } ``` 在上面的示例,divide 方法会抛出一个 ArithmeticException 异常,因为除数为零。在 catch ,我们对该异常进行处理,并输出相应的信息。无论是否发生异常,finally 的代码都会执行,输出 "finally 的代码"。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值