有return的情况下try catch finally的执行顺序
前言,在写java 异常捕捉块的时候,有时候用到return,有时有各种情况,不仔细分析的化就会出现意想不到的问题,所以我测试一般情形,用于记录一下。
情景1:try{}catch{}finally{}return 在这种情况下代码顺序执行
如:
package ming; public class Testt { public static int a() throws Exception{ int a=0; try { System.out.println(1/0); } catch (Exception e) { e.printStackTrace(); }finally { a=9; } return a; }
//即使出现了异常,代码从上往下执行...不含糊 public static void main(String[] args) throws Exception{ int a = a(); System.out.println(a);// 返回值为9 } }
情景2:try{}catch{throw e;}finally{}return 如果在catch这个块把异常抛出去,此时你不能获取返回值。
如:
package ming; public class Testt { public static int a() throws Exception { int a = 0; try { System.out.println(1 / 0); } catch (Exception e) { throw new Exception(e); } finally { a = 9; } return a; } public static void main(String[] args) throws Exception { int a = a(); System.out.println(a);//此时没有什么答案,仅仅抛出了一个异常而已,代码依然是从上往下执行 } }
情景3:try{return}catch{}finally{}return 这样的结构其实最后的return 只是为了防止try语块没有返回值,如果try有返回值,最后finally 大括号后面的代码不会执行的。
执行流程也是从上往下,只是遇到了return 了,代码去执行finally的,然后返回try执行,最后finally后面的代码就不会去执行了,因为有返回值了。
如:
package ming; public class Testt { public static int a() throws Exception { int a = 0; try { a=1; return a; } catch (Exception e) { e.printStackTrace(); } finally { a = 9; } a=10;//这代码是没有执行的 return a; } public static void main(String[] args) throws Exception { int a = a(); System.out.println(a);//输出1 } }
情景4:try{return}catch{throw}finally{} 在返回值之前抛出异常,显然最后没有什么结果了
如:
package ming; public class Testt { public static int a() throws Exception { int a = 0; try { a=1; System.out.println(1/0); return a; } catch (Exception e) { throw new Exception(e); } finally { a = 9; } } public static void main(String[] args) throws Exception { int a = a(); System.out.println(a); } }
情景4:try{return}catch{throw}finally{return} 在返回值之前抛出异常,finally 有return情况下,最后显然返回finally return的值了。
如:
package ming; public class Testt { public static int a() throws Exception { int a = 0; try { a=1; System.out.println(1/0); return a; } catch (Exception e) { throw new Exception(e); } finally { a = 9; return a; } } public static void main(String[] args) throws Exception { int a = a(); System.out.println(a);//返回值为9 } }
情景5:try{return}catch{return}finally{return} 依然以finally最后的return 作为返回值
如:
package ming; public class Testt { public static int a() throws Exception { int a = 0; try { a=1; System.out.println(1/0); return a; } catch (Exception e) { a=10; return a; } finally { a = 9; return a; } } public static void main(String[] args) throws Exception { int a = a(); System.out.println(a);//返回值为9 } }
情景6:try{return}catch{return}finally{} 如果try中异常返回catch中返回值,否则返回try中的
如:
package ming; public class Testt { public static int a() throws Exception { int a = 0; try { a=1; System.out.println(1/0); return a; } catch (Exception e) { a=10; return a; } finally { a = 9; } } public static void main(String[] args) throws Exception { int a = a(); System.out.println(a);//返回10 } }
情景7:我们把返回值类型改为对象类型测试一下:此时跟基本类型不一样,这是因为java 是值传递而不是引用传递
如:
package ming; public class Testt { public static Stu a() throws Exception { Stu stu=new Stu(); try { stu.setName("张三");; return stu; } catch (Exception e) { } finally { stu.setName("李四");; } return stu; } public static void main(String[] args) throws Exception { Stu stu = a(); System.out.println(stu.getName());//此时返回李四 } } class Stu{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
总结一下:
1.不管有木有出现异常,finally块中代码都会执行;
2.当try和catch中有return时,finally仍然会执行,执行是try,如果有异常就执行catch,最后依然执行finally,即使有return,代码先忽视return,从上往下执行,然后返回代码try 或catch中的return。如果fianlly有return ,代码就不会执行try 或catch的return。
3.finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
4.如果catch中抛出异常,你不会得到你的返回值。这在设计程序的时候要注意这个问题。
5. finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中 return已经确定的返回值
可能影响也可能不影响指的是:因为java 是值传递而不是引用传递