一、finally语句不会被执行的情况,至少有如下两种
- try语句没有执行到,如在try语句之前就返回了,就这样finally语句就不会执行,说明finally语句被执行的前提是相应的try语句被执行到。
- 在try块中有System.exit(0)(是终止java虚拟机JVM的);语句,连JVM都停止了,所有都结束了,finally也不会被执行到。
二、return语句的关系
- finally语句在return语句执行之后return返回之前执行
public class FinallyReturnTest { public static void main(String[] args) { System.out.println(test()); } public static String test() { try { System.out.println("try block"); return getResult(); } finally { System.out.println("finally block"); } } public static String getResult() { System.out.println("get result"); return "result"; }}返回结果
try block
get result
finally block
result
Process finished with exit code 02.try中的返回值可能因为finally里的修改也可能不变
test1:
public class FinallyReturnTest1 { public static void main(String[] args) { System.out.println(test()); } public static int test() { int b = 20; try { System.out.println("try block"); return b += 80; } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); if (b > 25) { System.out.println("b>25, b = " + b); } b = 150; } return 2000; }}返回结果
try block
finally block
b>25, b = 100
100test2:
public class FinallyReturnTest2 { public static void main(String[] args) { System.out.println(getMap().get("KEY")); } public static Map<String, String> getMap() { Map<String, String> map = new HashMap<>(); map.put("KEY", "INIT"); try { map.put("KEY", "TRY"); return map; } catch (Exception e) { map.put("KEY", "CATCH"); } finally { map.put("KEY", "FINALLY"); map = null; } return map; }}
返回结果
FINALLY
Process finished with exit code 03、try块里的return语句在异常的情况下不会被执行,这样具体返回哪个看情况
①catch和finally块里无返回语句,返回finally外的return语句。
②如果catch块里无返回语句,finally里有返回语句,返回finally的return语句。
③如果catch块里有return语句,执行的情况和try一样,finally有返回语句,执行finally中的返回语句。
三、字节码角度理解
public int get();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=1, locals=4, args_size=1
0: iconst_0 将int型0推送至栈顶(操作数栈) 1: istore_1 将栈顶int型数值存入第二个本地变量(局部变量表) 2: iconst_2 将int型2推送至栈顶 3: ireturn 从当前方法返回int,返回finally中的return值 2 4: astore_1 将栈顶引用型数值存入第二个变量(出现异常,将Exception存入局部变量表) 5: aload_1 将第二个引用型本地变量推送至栈顶 6: invokevirtual #3// Method java/lang/Exception.printStackTrace:()V 调用Exception实例方法 9: iconst_1 将int型1推送至栈顶 10: istore_2 将栈顶int型数值存入第三个本地变量 11: iconst_2 将int型2推送至栈顶 12: ireturn 从当前方法返回int,返回finally中的return值 13: astore_3 将栈顶引用型数值存入第四个变量 14: iconst_2 将int型2推送至栈顶 15: ireturn 从当前方法返回int,返回finally中的return值 2 Exception table: from to target type 0 2 4 Class java/lang/Exception 0 2 13 any 4 11 13 any LineNumberTable: line 7: 0 line 12: 2 line 8: 4 line 9: 5 line 10: 9 line 12: 11