图片于2017.5泰国团建拍摄。

在开发或面试过程中我们或多或少的会遇到try catch finlly代码块中同时含有return的情况来判断return的值是多少。
不卖关子了直接总结规律。

  1. 函数执行到return不一定会直接返回(比如try和catch里面的),对与值类型变量会开辟一块当前方法体返回类型的空间(及值的拷贝),对于引用类型会存着引用地址的拷贝,该结果会被第二个return(finally里面的)覆盖。
  2. 函数执行到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会影响返回结果。

参考

JavaSE之彻底搞懂try,catch,finally与return的执行