A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 石德志 于 2012-2-15 23:01 编辑

异常处理中的finally语句块在什么情况不执行?若遇到return语句提前返回呢?求具体使用情况。

评分

参与人数 1技术分 +1 收起 理由
唐秀启 + 1

查看全部评分

9 个回复

正序浏览
finally{}一般存放是一定被执行的代码,比如我们常做的关闭资源动作,但有一种特出情况finally{}不会被执行,那就是系统推出的时候,System.exit(0).
回复 使用道具 举报
侯丽星 黑马帝 2012-2-15 09:43:37
9#
本帖最后由 侯丽星 于 2012-2-15 09:45 编辑

http://www.ibm.com/developerworks/cn/java/j-lo-finally/
该网址对于你这个问题给予了详细的解答,上面有很详细的文字及代码分析~

我总结如下:
只有与 finally 相对应的 try 语句块得到执行的情况下,finally 语句块才一定会执行。当然finally一定执行的前提是:
try 语句块中无 System.exit (0) 语句,或者, try 语句块或者 catch 语句块没有被打断(interrupted)或者被终止(killed)。
回复 使用道具 举报
一般情况下,finally中存放的是一定会被执行的代码,也就是关闭资源代码,因为资源必须释放。finally只有一种情况下不会被执行,当执行到System.exit(0)的时候,finally不会被执行。System.exit(0)这段代码表示系统退出,JVM结束。
回复 使用道具 举报
马欢 黑马帝 2012-2-15 09:07:45
7#
问题分析

首先来问大家一个问题:finally 语句块一定会执行吗?

很多人都认为 finally 语句块是肯定要执行的,其中也包括一些很有经验的 Java 程序员。可惜并不像大多人所认为的那样,对于这个问题,答案当然是否定的,我们先来看下面这个例子。

清单 1.

               
public class Test {
public static void main(String[] args) {
System.out.println("return value of test(): " + test());
     }

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


清单 1 的执行结果如下:

the previous statement of try block
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.bj.charlie.Test.test(Test.java:15)
at com.bj.charlie.Test.main(Test.java:6)


另外,如果去掉上例中被注释的两条语句前的注释符,执行结果则是:

return value of test(): 0


在 以上两种情况下,finally 语句块都没有执行,说明什么问题呢?只有与 finally 相对应的 try 语句块得到执行的情况下,finally 语句块才会执行。以上两种情况,都是在 try 语句块之前返回(return)或者抛出异常,所以 try 对应的 finally 语句块没有执行。

回复 使用道具 举报
只有系统关闭了,finally才不会执行。即使你在try或catch中使用了return,finally还是一样会执行的
回复 使用道具 举报
所谓"异常处理中的finally语句块不执行,若try 中有return语句提前返回“,只是一个假象,其实java 还是会执行finally内语句的,如:
  1. class  Test
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 System.out.println("return: "+fun());
  6.         }
  7.         static int fun()
  8.         {       
  9.           int i = 1;
  10.           try
  11.           {
  12.                   return i;
  13.           }
  14.           finally
  15.           {
  16.           ++i;
  17.           // System.out.println(i);
  18.           // return i;
  19.           }
  20.         }
  21. }
复制代码
return: 1, 好像finally内的“++i”没执行,只是个错觉,取消finally内的那两个注释语句,你就会恍然大悟了!那为何之前“return: 1”?这是java 执行机制的问题,因try 已返回“1”,虽然后面会执行finally内的“++i”,但不会追溯之前送出的 i:1。
回复 使用道具 举报
异常处理中的finally语句块在什么情况不执行?

当你捕获到异常的时候,在处理异常的时候你完全可以System.exit(0);命令虚拟机,在执行异常处理的时候,虚拟机都退出了,又怎么能执行finally块中的代码呢。

如果你在捕获异常后处理为System.exit(1);停止异常的执行,那么finally块不会被执行。因为finally要在try块或者catch块之后执行,在catch块中的异常停止了,代码也就是不执行了,所以finally块也没有机会被执行。

因为程序是一条一条的先后顺序执行的。第一条没有执行那么第二条就不会执行。就算是分支判断语句,也要先进行首先的判断,然后才进行后续代码的执行。
回复 使用道具 举报
本帖最后由 陈丹阳 于 2012-2-15 09:31 编辑

finally里面放的是释放资源等操作。。

评分

参与人数 1技术分 +1 收起 理由
唐秀启 + 1

查看全部评分

回复 使用道具 举报
  1. class FinallyDemo
  2. {
  3.         public static void main(String args[]){
  4.                 test();
  5.         }
  6.        
  7.         public static int test(){
  8.         try
  9.         {
  10.                 System.out.println("try....");
  11.                 System.exit(1);
  12.                 return 2;
  13.         }
  14.         finally
  15.         {
  16.                 System.out.println("fianlly....");
  17.         }
  18.         }
  19. }
复制代码
遇到System.exit命令才不执行,一般情况是表示一定会执行的代码。try里面有提前返回它依然执行。


关于try里面有return的情况

如果finally中没有return那么finally中的code就在return之前执行。但这种情况下如果你在finally对要返回的变量做了改变,返回值也不会改变。
如果finally中有return,一般的编译器会提示警告,try中的return将不会执行。

评分

参与人数 1技术分 +1 收起 理由
唐秀启 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马