在finally语句块中使用return会导致以下两种异常情况出现:
一、会覆盖try或catch的return语句
public class MyTest {
public int test() throws ArrayIndexOutOfBoundsException{
try {
int a[] = new int[2];
System.out.println("try");
System.out.println("Access element three :" + a[1]);//不会抛出异常
return 1;
} finally {
System.out.println("finally");
return 2;
}
}
public static void main(String args[]){
MyTest my = new MyTest();
int a = 0;
try {
a = my.test();
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception thrown :" + e);
}
System.out.println("val:" + a);
}
}
当try或catch语句块和finally同时出现return且没有异常抛出时,程序执行的顺序为:try/catch return前的语句->try/catch return语句->finally return前的语句->finally return语句。当执行try/catch return语句时并不会返回到上一级,而是会继续往下执行finally语句的内容。执行到finally中return语句才会最终返回到上一级。
运行结果为
try
Access element three :0
finally
val:2
为了避免这种情况出现,我们一般不会在finally中使用return,此时,执行的顺序便会变成:try/catch return前的语句->finally的语句->try/catch return语句。
二、finally中使用return会让异常无法向上一级抛出,使本来应该报错的地方没有报错。
当然,如果能在本方法内就通过catch捕捉异常并把异常消化掉就可以避免这种情况出现。如果不能的话就会导致异常被return吞噬,不能被上一级方法调用或者java虚拟机捕获的情况发生。
public class MyTest {
public int test() throws ArrayIndexOutOfBoundsException{
try {
int a[] = new int[2];
System.out.println("try");
System.out.println("Access element three :" + a[3]);//抛出异常
return 1;
} finally {
System.out.println("finally");
return 2;
}
}
public static void main(String args[]){
MyTest my = new MyTest();
int a = 0;
try {
a = my.test();
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception thrown :" + e);
}
System.out.println("val:" + a);
}
}
当在finally中使用return且向上一级抛出异常时,即使出现索引超出异常时也不能被捕捉到。
try
finally
val:2
试着注释掉finally中的return语句
便会得到以下的结果
try
finally
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3
val:0



