首先来看个题目
下列有关finally语句块说法正确的是()
A.不管catch是否捕获异常,finally语句块都是要被执行的B.在try语句块或catch语句块中执行到System.exit(0)直接退出程序
C.finally块中的return语句会覆盖try块中的return返回
D.finally 语句块在catch语句块中的return语句之前执行
大家先思考一下,正确答案附在文章后方。有困惑的可以接着看
A:finally代码块只要程序进入到了try,不管是否catch是否捕获到异常,它都会执行,通常用于资源回收。无论是否发生异常,都要释放资源
B:System类中有一个静态方法exit(int status),当传入0时,会终止当前运行的Java虚拟机。
关于C和D两个选项,在这里详细给大家总结一下
例1:try catch finally中都没有return
public static int test1() {
try {
System.out.println("try代码块");
}catch(Exception e) {
System.out.println("catch代码块");
}finally {
System.out.println("finally代码块");
}
return 1;
}
程序会按照顺序执行,最终返回1
运行结果:
例2:try中有return,和finally外面有return
public static int test2() {
try {
System.out.println("try代码块");
return 1;
}catch(Exception e) {
System.out.println("catch代码块");
}finally {
System.out.println("finally代码块");
}
return 2;
}
首先会执行try中的代码,打印出"try代码块",然后再执行return 1。注意,这里虽然程序执行了return 1,但是并没有将return返回,而是将值先保存起来 ,接下来再执行finally中的代码,打印出"finally代码块",因为在try中return了,所以执行完finally后会将刚才的1返回
运行结果:
例3:catch中有return和finally外面有return
这里分为有异常和无异常两种情况
首先来看无异常
public static int test3() {
try {
System.out.println("try代码块");
}catch(Exception e) {
System.out.println("catch代码块");
return 1;
}finally {
System.out.println("finally代码块");
}
return 2;
}
无异常的话,程序会按照顺序执行,这个没什么问题
运行结果
再来看有异常的情况
public static int test3() {
try {
int[] array = {1, 2, 3};
System.out.println(array[3]);
}catch(Exception e) {
System.out.println("catch代码块");
return 1;
}finally {
System.out.println("finally代码块");
}
return 2;
}
程序会先首先进入到try中,当执行到System.out.println(array[3]);时会发生数组越界异常,所以此时会去执行catch中的代码,打印"catch代码块",接着执行return 1。但此时并没有将一返回,而是继续向下执行,打印"finally代码块"。最后将1返回,所以return 2不会被执行到
运行结果
例4:try中有return和finally中有return
public static int test4() {
try {
System.out.println("try代码块");
return 1;
}catch(Exception e) {
System.out.println("catch代码块");
}finally {
System.out.println("finally代码块");
return 2;
}
}
首先程序进入到try中,打印"try代码块",接着执行return 1,只是将值保存起来,并没有返回。然后再执行finally中的代码,打印"finally代码块",再执行return 2。此时的return 2会覆盖return 1并返回
运行结果
例5:catch中有return和finally中有return
这里也分两种情况讨论
无异常的情况
public static int test5() {
try {
System.out.println("try代码块");
}catch(Exception e) {
System.out.println("catch代码块");
return 1;
}finally {
System.out.println("finally代码块");
return 2;
}
}
此时程序会按照顺序执行。首先进入到try中,打印"try代码块"。接着进入到finally中,打印"finally代码块",再执行return 2并返回
运行结果
有异常的情况
public static int test5() {
try {
int[] array = {1, 2, 3};
System.out.println(array[3]);
}catch(Exception e) {
System.out.println("catch代码块");
return 1;
}finally {
System.out.println("finally代码块");
return 2;
}
}
首先进入到try中,当执行到System.out.println(array[3]);会发生数组越界异常,程序会进入到catch中,打印"catch代码块",再执行return 1,但并没有将1返回,只是先将1保存起来。然后执行finally中的代码,打印"finally代码块"。最后执行return 2,将return 1保存的值覆盖并返回
运行结果
例6:try,catch,finally中都有return
这里也有两种情况,无异常的情况相信大家看了上面情况都已经了然。下面我们来看有异常的情况
public static int test6() {
try {
int[] array = {1, 2, 3};
System.out.println(array[3]);
return 1;
}catch(Exception e) {
System.out.println("catch代码块");
return 2;
}finally {
System.out.println("finally代码块");
return 3;
}
}
程序先进入到try中,当执行到System.out.println(array[3]);时,发生了数组越界异常,return 1不会被执行到。然后程序进入到catch中,打印“catch代码块”,再执行return 2。不会返回,只是保存值,最后执行finally中的代码,打印"finally代码块",接着执行return 3覆盖return 2中保存的值并返回
运行结果
总结:如果try和catch中有finally,并且finally中有return,最终都会将finally的值返回。所以finally中最好不要写return,否则try或者catch中的return 将变得毫无意义。对于执行try或者catch中的return 后不返回感到困惑的伙伴可以用debug调试一下。谢谢大家
题目的答案:ABC