若try或catch中没有return语句,则按正常执行流,从上到下,finally里的所有修改都生效。

这里讨论的是try或catch里有return或throw语句的情形,此情形比较让人迷惑。

总结如下:

finally语句在try或catch的return或throw语句执行之后返回之前执行 且 finally里的语句不影响try或catch中已经确定的返回值(但能改变try或catch中引用对象里的成员,这跟final修饰的效果很像),除非finally里也有return或者throw等终止方法的语句,则就不会跳回try或catch执行,直接停止。

一般不建议在finally里return,在Eclipse里会警告 finally block does not complete normally 。

示例:

0、try中没有return语句,finally的修改生效

 class FinallyTest0 {
public static void main(String[] args) {
System.out.println(test0());
} public static int test0() {
int b = 20;
try {
System.out.println("try block"); b += 80;
} catch (Exception e) {
b += 15;
System.out.println("catch block");
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
b += 50;
}
return b;
}
}

执行结果:

try block
finally block
b>25, b = 100
150

此情形很简单,无须多言。当然,将return b;放在finally里的末尾效果也一样。

1、finally语句在try中return语句执行之后且返回之前执行的

 class FinallyTest1 {
public static void main(String[] args) {
System.out.println(test1());
} public static int test1() {
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);
}
}
return b;
}
}

执行结果:

try block
finally block
b>25, b = 100
100

说明return语句已经执行了再去执行finally语句,不过并没有直接返回,而是等finally语句执行完了再返回结果。此外,从这也可以看出,程序执行完finally后就回到try中返回了,程序最后的return b并不会执行。

另一个示例:

 class FinallyTest1 {
public static void main(String[] args) {
System.out.println(test11());
} public static String test11() {
try {
System.out.println("try block");
return test12();
} finally {
System.out.println("finally block");
}
} public static String test12() {
System.out.println("return statement");
return "after return";
}
}

执行结果:

try block
return statement
finally block
after return

说明try中的return语句先执行了但并没有立即返回,等到finally执行结束后再返回。

2、finally块中的return语句会覆盖try块中的return返回

 class FinallyTest2 {
public static void main(String[] args) {
System.out.println(test2());
} public static int test2() {
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);
}
return 200;
}
// return b;//不可达
}
}

执行结果:

try block
finally block
b>25, b = 100
200

说明finally里的return直接返回了,不管try中是否还有返回语句。

3、try中要返回的值不因finally里的修改而改变

 class FinallyTest3 {
public static void main(String[] args) {
System.out.println(test3());
} public static int test3() {
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
100

说明finally里的修改不改变try里的返回值。

另一个示例:(虽然对象的内容变了,但引用的是哪个对象并没变)

 class FinallyTest3 {
public static void main(String[] args) {
System.out.println(getMap().get("KEY").toString());
} public static Map<String, String> getMap() {
Map<String, String> map = new HashMap<String, String>();
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

变量map是对象的引用,虽然finally中map.put使得引用的对象的内容变了,但对引用变量map的修改map=null并没对return的返回值起作用(返回值没变为null)。

注意体会 对引用的修改对引用对象的修改 两者的区别,这与final修饰一个引用变量的情形相似,虽然此时引用变量不可更改,但却可以修改引用对象里的内容。

如果把最后的 return map; 放到finally里末尾,则由上面的2知try里的return的值变了。示例如下:

 class FinallyTest3 {
public static void main(String[] args) {
System.out.println(getMap().get("KEY").toString());
} public static Map<String, String> getMap() {
Map<String, String> map = new HashMap<String, String>();
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;
}
// return map;
}
} 结果:(由于try里返回了null,导致后续访问异常)
Exception in thread "main" java.lang.NullPointerException
at buaa.act.ucar.imtg.main.FinallyTest6.main(Test.java:23)

4、catch中的情形与try的一样

在try块发生异常的情况下其里面的return语句不会被执行,转到catch,catch里的执行情形与上述try的一样。

示例1及结果(对应0):

 class FinallyTest4 {
public static void main(String[] args) {
System.out.println(test4());
} public static int test4() {
int b = 20;
try {
System.out.println("try block");
b = b / 0;
return b += 80;
} catch (Exception e) {
b += 15;
System.out.println("catch block");
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
b += 50;
}
return b;
}
}
try block
catch block
finally block
b>25, b = 35
85

在try里return之前发生了除0异常,所以try中的return不会被执行到,而是接着执行捕获异常的catch语句和最终的finally语句,此时两者对b的修改都影响了最终的返回值。

示例2及结果(对应1、3):

 class FinallyTest4 {
public static void main(String[] args) {
System.out.println(test4());
} public static int test4() {
int b = 20;
try {
System.out.println("try block");
b = b / 0;
return b += 80;
} catch (Exception e) {
System.out.println("catch block");
return b += 15;
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
b += 50;
}
}
}
try block
catch block
finally block
b>25, b = 35
35

说明了发生异常后,catch中的return语句先执行,确定了返回值后再去执行finally块,执行完了catch再返回,finally里对b的改变对返回值无影响,原因同前面try的一样。

示例3及结果(对应2):在finally里末尾加上return b;则最后打印出的b值为85。

参考资料:http://www.cnblogs.com/lanxuezaipiao/p/3440471.html

Java finally语句是在try或catch的retrurn之前还是之后执行的更多相关文章

  1. Java知多少(47)多重catch语句的使用

    某些情况,由单个代码段可能引起多个异常.处理这种情况,你可以定义两个或更多的catch子句,每个子句捕获一种类型的异常.当异常被引发时,每一个catch子句被依次检查,第一个匹配异常类型的子句执行.当 ...

  2. Java finally语句到底是在return之前还是之后执行?

    网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正确的,经过我试验,至少有两种情况下fina ...

  3. Java finally语句到底是在return之前还是之后执行(JVM字节码分析及内部体系结构)?

    之前看了一篇关于"Java finally语句到底是在return之前还是之后执行?"这样的博客,看到兴致处,突然博客里的一个测试用例让我产生了疑惑. 测试用例如下: public ...

  4. 【转】Java finally语句到底是在return之前还是之后执行?

    网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正确的,经过试验,至少有两种情况下final ...

  5. Java static{}语句块详解

    [转自] http://blog.csdn.net/lubiaopan/article/details/4802430 static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一 ...

  6. Java finally语句到底是在return之前还是之后执行

    看过网上关于Java中异常捕获机制try-catch-finally块中的finally语句是不是一定会被执行的讨论也有很多. 首先明确一点,下面两种情况finally肯定是不执行的: 1). ret ...

  7. 【Demo 0002】Java基础-语句

    本章学习要点:        1.  掌握Java关健语句使用方法;          2.  理解与语句相关的关键字用法; 一.Java 关键语句        Java语句以及关联关键字与C完全相 ...

  8. 7#Java基本语句语法

    Java基本语句语法https://github.com/DuGuQiuBai/Java/blob/master/day03/day03%E6%80%BB%E7%BB%93.txt 1:位运算符(了解 ...

  9. Java流程语句

    流程控制语句 if语句: if语句的执行流程 例子: public class IfDemo01 { public static void main(String[] args) { int x = ...

随机推荐

  1. elk 使用中遇到的问题(kafka 重复消费)

    问题描述: 在使用过程中,当遇到大量报错的时候,我们到eagle后台看到报错的那个consumer的消费情况到到lag 远远大于0(正常情况应该为0),activie  节点没有,kibana面板上没 ...

  2. Axure chrome 扩展显示已损坏的解决方法

    下载地址 链接:https://pan.baidu.com/s/11K3t_mvgJg51siO_jNRejg 提取码:goz1 如果链接失效,请留言或站内信提醒我更新 疑问 之前用的好好的Axure ...

  3. Shell脚本大量示例

     Shell基础之控制流结构 一.控制结构 几乎所有的脚本里都有某种流控制结构,很少有例外.流控制是什么?假定有一个脚本,包含下列几个命令: #!/bin/sh # make a directory ...

  4. 一种3D空间的柱状多边形检测实现

    最近无意中拓展出这个东西,基于之前写的2D多边形检测: http://www.cnblogs.com/hont/p/6105997.html 而判断两条线相交的方法替换成了我后来写的差乘判断: htt ...

  5. Atitit 图像处理 halcon类库的使用  范例边缘检测 attilax总结

    Atitit 图像处理 halcon类库的使用  范例边缘检测 attilax总结 1.1. 安装halcon11 ..体积大概1g压缩模式1 1.2. Halcon的科技树1 1.3. 启动 &qu ...

  6. linq筛选唯一

    var sizelist= (from p in stockList select p.Size).Distinct().ToArray(); newslist = newslist.OrderBy( ...

  7. 【Android】2.0 第2章 初识Android App

    分类:C#.Android.VS2015:  创建日期:2016-02-04 一.认识Android操作系统 Android最早由安迪•罗宾(Andy Rubin)创办,2007年被Google公司收 ...

  8. 把虚拟教练带回家,「EuMotus」想用AI实现高精度运动反馈系统

    https://36kr.com/p/5089139.html 无需穿戴设备,只需一个红外摄像头和+已安装好EuMotus专利软件的手提电脑 由政府主导的高达2200亿美金的健身与运动支出,15%的健 ...

  9. 实战mysql分区

    前些天拿到一个表,将近有4000w数据,没有任何索引,主键.(建这表的绝对是个人才) 这是一个日志表,记录了游戏中物品的产出与消耗,原先有一个后台对这个表进行统计.....(这要用超级计算机才能统计得 ...

  10. 《java虚拟机》汇总所有关键要点

    一  .java虚拟机底层结构详解 我们知道,一个JVM实例的行为不光是它自己的事,还涉及到它的子系统.存储区域.数据类型和指令这些部分,它们描述了JVM的一个抽象的内部体系结构,其目的不光规定实现J ...