关于try-catch-finally的用法我就不多说了。网上搜一下,资料很多。
这里我想主要讨论下在finally块加入return语句,屏蔽异常的问题。
我们先来看这样一段代码,
代码1:
view plaincopy to clipboardprint?
public class FinallyTest {
public static void main(String[] args) {
new FinallyTest().print();
}
public void print() {
int i = -1;
try {
Thread.sleep(1);
i = 1 / 0;
} catch (Exception e) {
System.out.println("at catch block step 1.");
throw e;
} finally {
System.out.println("at finally block i = " + i);
}
}
}
public class FinallyTest {
public static void main(String[] args) {
new FinallyTest().print();
}
public void print() {
int i = -1;
try {
Thread.sleep(1);
i = 1 / 0;
} catch (Exception e) {
System.out.println("at catch block step 1.");
throw e;
} finally {
System.out.println("at finally block i = " + i);
}
}
}
以上代码在Eclipse里是不会编译通过的,因为在catch块中throw了一个异常,而print方法并没有声明要抛出异常。
现在我们修改代码,让它能够通过编译,代码2:
view plaincopy to clipboardprint?
public class FinallyTest {
public static void main(String[] args) throws Exception {
new FinallyTest().print();
}
public void print() throws Exception {
…
public class FinallyTest {
public static void main(String[] args) throws Exception {
new FinallyTest().print();
}
public void print() throws Exception {
…
就是在print和main方法后加throws Exception,然后运行,看运行结果:
view plaincopy to clipboardprint?
at catch block step 1.
at finally block i = -1
Exception in thread "main" java.lang.ArithmeticException: / by zero
at wxhx.csdn2.FinallyTest.print(FinallyTest.java:12)
at wxhx.csdn2.FinallyTest.main(FinallyTest.java:5)
at catch block step 1.
at finally block i = -1
Exception in thread "main" java.lang.ArithmeticException: / by zero
at wxhx.csdn2.FinallyTest.print(FinallyTest.java:12)
at wxhx.csdn2.FinallyTest.main(FinallyTest.java:5)
程序先是走到了catch块的第一句,打印了at catch block step 1.
但并没有紧接着去throw e,即没有立刻抛出这个异常,之所以这样说,是因为异常的信息是在finally块的打印信息之后才打印的。
这个例子告诉我们,finally不管出现异常与否,都必须去执行的代码。(如果中途终止了jvm,就不必去执行了)
那么何时执行finally块中的代码呢?
在这个例子中,try块中有异常抛出,所以finally块中的代码是在执行了catch语句之后、退出方法之前被执行的 (如果这里执行了throw e,则方法就退出了) 。
下面再看另外一个代码,代码3:
view plaincopy to clipboardprint?
public class FinallyTest {
public static void main(String[] args) {
new FinallyTest().print();
}
public void print() {
int i = -1;
try {
Thread.sleep(1);
i = 1 / 0;
} catch (Exception e) {
System.out.println("at catch block step 1.");
throw e;
} finally {
System.out.println("at finally block i = " + i);
return;
}
}
}
public class FinallyTest {
public static void main(String[] args) {
new FinallyTest().print();
}
public void print() {
int i = -1;
try {
Thread.sleep(1);
i = 1 / 0;
} catch (Exception e) {
System.out.println("at catch block step 1.");
throw e;
} finally {
System.out.println("at finally block i = " + i);
return;
}
}
}
这段代码与之前相比,在finally块中增加了return语句。
虽然在catch块中有throw e语句,但在print方法后并不用声明throws Exception,也可以通过编译。
因为在try块中有Thread.sleep(1);语句,所以必须要捕获InterruptedException,但在这种情况下,即使我们把catch块去掉了,也不会有问题,这是怎么回事呢?
因为在finally块中的return语句屏蔽了异常。
经过代码2我们已经知道了,异常在finally块被执行之前,虽然会执行catch块中的代码,但并不会退出方法,在退出方法之前,会转向finally块中执行,而在finally块中又恰好有return语句,所以方法就正常退出了,在try块中产生的异常就不会有机会被抛出。
总结:
1.执行retrun的话就会跳出函数返回了.
2.try-catch-finally的顺序是
没有异常的话,try一直执行至try中retrun前,就会去执行finally中的代码,如果finally中无retrun就会做try中的retrun,try中也没有retrun的话就会做try-catch-finally外的代码了.
如果在try中有异常的话,在异常处就会抛出,try中的就不再执行,去执行catch中的代码(前题是抛出的是catch中的异常,能被catch),catch中如果碰到retrun或到尽头,就会去执行finally中的代码,finally中的代码如有retrun就retrun,无就去catch中的retrun,如果catch都无retrun,就会执行try-catch-finally外的代码.
3.可见finally中的代码是一定会全执行的(retrun前)
4.retrun后的代码是无效的.
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/bzwm/archive/2009/02/13/3885720.aspx