图片于2017.5泰国团建拍摄。
在开发或面试过程中我们或多或少的会遇到try catch finlly代码块中同时含有return的情况来判断return的值是多少。
不卖关子了直接总结规律。
- 函数执行到return不一定会直接返回(比如try和catch里面的),对与值类型变量会开辟一块当前方法体返回类型的空间(及值的拷贝),对于引用类型会存着引用地址的拷贝,该结果会被第二个return(finally里面的)覆盖。
- 函数执行到try里面的内容,一定会执行finally里面的语句块,除非try里面有类似System.exit()的方法。
基于上述的规律我们看一下如下列子
class Untitled {
public static void main(String[] args) {
System.out.println(""+m1());
}
private static int m1() {
int a = 10;
try {
a = 20;
throw new RuntimeException();
} catch (Exception e) {
a = 30;
return a;
} finally {
a = 40;
return a;
}
}
}
输出结果是40。有两retrun 下面的会覆盖上面的所以会是40
class Untitled {
public static void main(String[] args) {
System.out.println(""+m1());
}
private static int m1() {
int a = 10;
try {
a = 20;
throw new RuntimeException();
} catch (Exception e) {
a = 30;
return a;
} finally {
a = 40;
}
}
}
输出结果是30。finally中没有return,虽然a=40,但是return在之前执行,已经在栈中开辟一块当前方法体返回类型的空间存放了30(值的拷贝)。所以a=40操作的变量a,不用影响return已经新开辟控件存储的30。
class Untitled {
public static void main(String[] args) {
System.out.println(""+m1());
}
private static StringBuilder m1() {
StringBuilder builder = new StringBuilder();
try {
builder.toString();
throw new RuntimeException();
} catch (Exception e) {
return builder;
} finally {
builder.append("1");
}
}
}
输出结果是1。StringBuilder是引用类型。return会拷贝引用地址。所以操作build会影响返回结果。