Java中finally关键字的几个坑

栏目: Java · 发布时间: 5年前

内容简介:java中的很多人都认为运行代码输出 :

java中的 finally 关键字通常与 try/catch 块一起使用。用来在方法结束前或发生异常时做一些资源释放的操作。虽然看起来很简单,在日常开发中也发现几个关于 finlla 问题。

finally 语句块一定会执行吗?

很多人都认为 finally 语句块是肯定要执行的,比如下面的代码,只要进入了 try/catch 块,不管有没有异常,都会执行 finllay 块 :

public static int test(){
        try {
            System.out.println("try block");
            int i = 1 / 0;
            return 0;
        } finally {
            System.out.println("finally block");
        }
    }

运行代码输出 :

try block
finally block
Exception in thread "main" java.lang.ArithmeticException: / by zero

但是回到这个问题,结果并不像大多人所认为的,答案是否定的,我们先来看下面这个例子:

public static int test(){
       try {
           System.out.println("try block");
           System.exit(0);
           return 0;
       } finally {
           System.out.println("finally block");
       }
   }

运行代码输出 :

try block

我们在 try 语句块中执行了 System.exit (0) 语句,终止了 Java 虚拟机的运行, finally 语句块还是没有执行。

如果执行了finally,函数返回值问题

public static int test(){
        try {
            System.out.println("try block");
            int i = 1 / 0; // 注释
            return 0;
        } catch (Exception e) {
            System.out.println("catch block");
            return 1;
        } finally {
            System.out.println("finally block");
            return 2;
        }
    }

对于上面的代码,相信大部分人都能知道输出值是 2 ,打印结果也确实是 2 ,就算把 int i = 1 / 0 这一行注释掉,打印结果也是 2 。所以在这里我们可以下结论 : finally 里的 return 语句会把 try/catch 块里的 return 语句效果给覆盖掉。

假如我们不在 finallyreturn ,结果会怎样?我们再看看下面的例子 :

public static int test(){
       int i = 999;
       try {
           System.out.println("try block");
           i = 1 / 0;
           return i;
       } catch (Exception e) {
           System.out.println("catch block");
           i = 100;
           return i;
       } finally {
           System.out.println("finally block");
           i = 200;
       }
   }

打印结果是 :

try block
catch block
finally block
 100

虽然调用了 finllay 改变了i的值,但是最后输出还是 100 ,为什么呢?我们可以通过分析字节码文件得到结果 :

 public static int test();
    Code:
       0: sipush        999
       3: istore_0
。。。
      29: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      32: ldc           #14                 // String catch block
      34: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      37: bipush        100
      39: istore_0
      40: iload_0
      41: istore_2
      42: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      45: ldc           #12                 // String finally block
      47: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      50: sipush        200
      53: istore_0
      54: iload_2
      55: ireturn
。。。

从字节码文件中可以看出,在 37:39 中把 100 存入 index 0 的位置,就是设置 i 的值为 100 ,在 40:41 中把 index 0 的值赋值给了 index 2 的位置,在 50:53 中把 200 存入 index 0 的位置,就是设置 i 的值为 200 ,最后在 54:55 中把 index 2 的值加载出来并返回,即最后返回的是 index 2 的值 100

对于这种情况我的理解就是在 return 的的时候会把返回值压入栈,并把返回值赋值给栈中的局部变量, 最后把栈顶的变量值作为函数返回值。所以在 finally 中的返回值就会覆盖 try/catch中 的返回值,如果 finally 中不执行 return 语句,在 finally 中修改返回变量的值,不会影响返回结果。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

網絡社會之崛起

網絡社會之崛起

曼威·柯司特 / 夏鑄九、王志弘 等 / 唐山 / 2000-11 / NT$550

本書解釋了今日重塑世界的兩股強大但相互衝突的潮流:全球化與認同。資訊科技的革命以及資本主義的再結構已經引動了網絡社會,並帶來了策略,除經濟行為的全球化、工作的彈性化與不穩定,以及真實的虛擬文化。但是,伴隨著資本主義的轉化與國家主義的消亡而來的,是集體認同的表達以火力十足的方式竄起。它們挑戰了全球化中的文化單一性以及對於生活、環境的控制。曼威.柯司特在本書中描繪了社會運動的根源、目標以及效果,包括了......一起来看看 《網絡社會之崛起》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码