java Finally代码块真的任何情况下都是执行的?
三种可能不执行finally代码块的情况- 在try代码块之外产生异常或者返回下是不会执行finally代码块的- 执行try代码块时候退出了JVM虚拟机- 在子线程执行try代码块或者catch代码块时候突然关闭了线程,也可能不执行finally代码块- 突然断电了也可能package simple;public class Test {public static voi
三种可能不执行finally代码块的情况
- 在try代码块之外产生异常或者返回下是不会执行finally代码块的
- 执行try代码块时候退出了JVM虚拟机
- 在子线程执行try代码块或者catch代码块时候突然关闭了线程,也可能不执行finally代码块
- 突然断电了也可能
package simple;
public class Test {
public static void main(String[] args) throws InterruptedException {
// 强制在try块中退出JVM也不会执行finally代码块,代码执行结果是不执行finally代码块
// System.out.println("return value of test(): " + testExit());
// 在try代码块之前返回或者抛异常都是不会执行finally代码块,执行结果是不执行finally代码块
// System.out.println("return value of test(): " + test());
// 子线程执行try代码块时候突然关闭线程了,也可能不会执行finally代码块,我的试验情况是会指定,但是不会保证一定执行。
myThread thread = testThread();
thread.start();
Thread.sleep(1000);
thread.isRunning = false;
System.out.println("main exit");
}
static class myThread extends Thread {
public boolean isRunning = true;
@Override
public void run() {
super.run();
System.out.println(Thread.currentThread().getName() + "\t begin running");
try {
while (isRunning) {
System.out.println("running");
// int i = 11 / 0;
}
if (isRunning == false) {
Thread.sleep(1000);
}
System.out.println(Thread.currentThread().getName() + "\t exit running");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
System.out.println("子线程");
}
};
}
public static myThread testThread() {
return new myThread();
}
/**
* 测试在try块中退出JVM
*
* @return
*/
public static int testExit() {
int i = 1;
try {
System.out.println("try block");
System.exit(0);
return i;
} finally {
System.out.println("finally block");
}
}
/**
* 测试在try块之外抛异常或者返回
*
* @return
*/
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");
}
}
}
关于finally代码块一定会执行的情况:
只有与 finally 相对应的 try 语句块得到执行的情况下,finally 语句块才会执行。不管 try 语句块正常结束还是异常结束,finally 语句块是保证要执行的。
如果 try 语句块正常结束,那么在 try 语句块中的语句都执行完之后,再执行 finally 语句块。如果 try 中有控制转移语句(return、break、continue)呢?那 finally 语句块是在try语句块中return控制转移语句之前执行;
如果 try 语句块异常结束,应该先去相应的 catch 块做异常处理,然后执行 finally 语句块。同样的问题,如果 catch 语句块中包含控制转移语句呢? finally 语句块是在这些控制转移语句之前,还是之后执行呢?我们给出实例代码。
代码执行结果 说明了 finally 语句块在 catch 语句块中的 return 语句之前执行
public class Test {
public static void main(String[] args) {
System.out.println("reture value of test() : " + test());
}
public static int test(){
int i = 1;
try {
System.out.println("try block");
i = 1 / 0;
return 1;
}catch (Exception e){
System.out.println("exception block");
return 2;
}finally {
System.out.println("finally block");
}
}
}
综上 finally 语句块是在 try 或者 catch 中的 return 语句之前执行的。更加一般的说法是,finally 语句块应该是在控制转移语句之前执行,控制转移语句除了 return 外,还有 break 和 continue。另外,throw 语句也属于控制转移语句。虽然 return、throw、break 和 continue 都是控制转移语句,但是它们之间是有区别的。其中 return 和 throw 把程序控制权转交给它们的调用者(invoker),而 break 和 continue 的控制权是在当前方法内转移。请大家先记住它们的区别。
参考文章:
IBM
更多推荐
所有评论(0)