Java中try,catch,finally代码执行顺序是怎么样的?如果带有return又是怎样的?这是面试常考的一个问题。
先给出结论:
1.如果try中没有异常,则顺序为try→finally;如果try中有异常,顺序为try→catch→finally,并且异常之后的代码不会执行。
2.当try或catch中带有return时,会先执行return前的代码,然后暂时保存需要return的信息,[对与值类型变量会开辟一块当前方法体返回类型的空间(及值的拷贝),对于引用类型会存着引用地址的拷贝],再执行finally中的代码,最后再通过return返回之前保存的信息。
还要注意,如果return的返回值参数是引用类型,还会影响return保存的信息。
中有return时,会直接在finally中退出,导致try、catch中的return失效。
这种写法,编译是可以编译通过的,但是编译器会给予警告,所以不推荐在finally中写return,这会破坏程序的完整性
下面给出一个本人测试的demo,包含了以上所有情况,基本上几个例子看完之后就弄明白了执行顺序了。
public class SeDemo {
/**
* 没有异常 try ,finally
* @return 3
*/
public static int divide(){
try {
return 1;
} catch (Exception e){
return 2;
} finally {
return 3;
}
}
/**
* 异常 try,catch,finally
* @return 3
*/
public static int divide1 (){
try {
int a = 1/0;
return 1;
} catch (Exception e){
return 2;
} finally {
return 3;
}
}
/**
* try ,finally
* @return 30
*/
public static int divide2 (){
int a;
try {
a = 10;
} catch (Exception e){
a = 20;
} finally {
a = 30;
}
return a;
}
/**
* try ,finally
* @return 10
*/
public static int divide3 (){
int a;
try {
a = 10;
return a;
} catch (Exception e){
a = 20;
} finally {
a = 30;
}
a++;
return a;
}
/**
* trh ,catch,finally
* @return 20
*/
public static int divide4 (){
int a;
try {
a = 10;
int b = 10 / 0;
} catch (Exception e){
a = 20;
return a;
} finally {
a = 30;
}
return a;
}
/**
* @return [1,3]
*/
public static List<Integer> divide5() {
List<Integer> list = new ArrayList<>();
try {
(1);
} catch (Exception e) {
(2);
} finally {
(3);
}
return list;
}
/**
* @return [1,3]
*/
public static List<Integer> divide6() {
List<Integer> list = new ArrayList<>();
try {
(1);
return list;
} catch (Exception e) {
(2);
} finally {
(3);
}
return list;
}
/**
* @return [1,2,3]
*/
public static List<Integer> divide7() {
List<Integer> list = new ArrayList<>();
try {
(1);
int a = 1/0;
} catch (Exception e) {
(2);
return list;
} finally {
(3);
}
return list;
}
}