面试被问finally 和 return,到底谁先执行?

经常有人面试被问到,finally 和 return,到底谁先执行呢?

为了解决这个问题,其实我们可以先想想 finally 是被用来干嘛的呢?它是被用来结束一些正常的收尾动作或结束标识。也就是说无论怎么样,finally 都会被最后执行。例如:一般在操作数据库时,用Jdbc连接池连接数据库后释放资源,需要 finally 来处理。再如 redis 连接,在获取连接池处理完数据的增删改查后,需要释放其连接池。

file

但是,如果 return 是在 finally 前面呢?或者在 finally 后面呢?我们先来看看 return 在 finally 前面时,如:

package com.test;

/**
 * 
 * 
 * @author Damon 
 * @date 2020年3月18日 上午11:02:08
 *
 */
public class App {
  public static void main(String[] args) {
    System.out.println("return result: " + test());
  }

  public static int test() {
    try {
      Thread.sleep(1);
      System.out.println("執行 return 1");
      return 1;// return 在try里,則先執行,再執行finally后才有可能执行该return
    }
    catch (InterruptedException e) {
      e.printStackTrace();
      return -1;
    }
    finally {
      System.out.println("执行 finally");
      //return 3;
    }
    //System.out.println("執行 return 2");
    //return 1;
  }
}

结果:

執行 return 1
执行 finally
return result: 1

也就是说,在执行 return 之前,先执行了 finally。

我们在看,如果 finally 前面有 return,在其内部也有 return:

package com.test;

/**
 * 
 * 
 * @author Damon 
 * @date 2020年3月18日 上午11:02:08
 *
 */
public class App {
  public static void main(String[] args) {
    System.out.println("return result: " + test());
  }

  public static int test() {
    try {
      Thread.sleep(1);
      System.out.println("執行 return 1");
      return 1;// return 在try里,則先執行,再執行finally后才有可能执行该return
    }
    catch (InterruptedException e) {
      e.printStackTrace();
      return -1;
    }
    finally {
      System.out.println("执行 finally");
      return 3;
    }
    //System.out.println("執行 return 2");
    //return 1;
  }
}

结果:

執行 return 1
执行 finally
return result: 3

其内部被 return 后,就不再执行前面那个 return 了。

我们再来看 return 在 finally 之后,如:

package com.test;

/**
 * 
 * 
 * @author Damon 
 * @date 2020年3月18日 上午11:02:08
 *
 */
public class App {
  public static void main(String[] args) {
    System.out.println("return result: " + test());
  }

  public static int test() {
    try {
      Thread.sleep(1);
      //System.out.println("執行 return 1");
      //return 1;// return 在try里,則先執行,再執行finally后才有可能执行该return
    }
    catch (InterruptedException e) {
      e.printStackTrace();
      //return -1;
    }
    finally {
      System.out.println("执行 finally");
      //return 3;
    }
    System.out.println("執行 return 2");
    return 1;
  }
}

结果:

执行 finally
執行 return 2
return result: 1

总结:finally 在 return 之后时,先执行 finally 后,再执行该 return;finally 内含有 return 时,直接执行其 return 后结束;finally 在 return 前,执行完 finally 后再执行 return。

接下来还有常被问到的是:Java 中 final、finally、finalize 的区别与用法:

  • final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。即如果一个类被声明为 final,意味着它不能作为父类被继承,因此一个类不能同时被声明为 abstract 的,又被声明为 final 的。变量或方法被声明为 final,可以保证它们在使用中不被修改。被声明为 final 的变量必须在声明时给赋予初值,而在以后的引用中只能读取,不可修改。被声明为 final 的方法也同样只能使用,不能重载。
  • finally 是异常处理语句结构的一部分,总是执行,常见的场景:释放一些资源,例如前面所说的 redis、db 等。在异常处理时提供 finally 块来执行任何清除操作,即在执行 catch 后会执行 finally 代码块。
  • finalize 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。


个人网站

技术分享博客

结束福利

开源实战利用 k8s 作微服务的架构设计代码:

https://gitee.com/damon_one/spring-cloud-k8s

欢迎大家 star,多多指教。


关于作者

  笔名:Damon,技术爱好者,长期从事 Java 开发、Spring Cloud 的微服务架构设计,以及结合docker、k8s做微服务容器化,自动化部署等一站式项目部署、落地。Go 语言学习,k8s研究,边缘计算框架 KubeEdge 等。公众号 程序猿Damon 发起人。个人微信 MrNull008,欢迎來撩。


欢迎关注 InfoQ: https://www.infoq.cn/profile/1905020/following/user

欢迎关注

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一. Java基础部分 7 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 9 6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? 9 7、char型变量中能不能存贮一个中文汉字?为什么? 9 8、用最有效率的方法算出2乘以8等於几? 9 9、请设计一个一百亿的计算器 9 10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、"=="和equals方法究竟有什么区别? 11 12、静态变量和实例变量的区别? 12 13、是否可以从一个static方法内部发出对非static方法的调用? 12 14、Integer与int的区别 13 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 13 16、下面的代码有什么不妥之处? 13 17、请说出作用域public,private,protected,以及不写时的区别 13 18、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? 14 19、构造器Constructor是否可被override? 15 20、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)? 抽象类中是否可以有静态的main方法? 15 21、写clone()方法时,通常都有一行代码,是什么? 15 22、面向对象的特征有哪些方面 15 23、java中实现多态的机制是什么? 17 24、abstract class和interface有什么区别? 17 25、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? 18 26、什么是内部类?Static Nested Class 和 Inner Class的不同。 19 27、内部类可以引用它的包含类的成员吗?有没有什么限制? 20 28、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 21 29、super.getClass()方法调用 21 30、String是最基本的数据类型吗? 22 31、String s = "Hello";s = s + " world!";这两行代码执行后,原始的String对象中的内容到底变了没有? 22 32、是否可以继承String类? 23 33、String s = new String("xyz");创建了几个String Object? 二者之间有什么区别? 23 34、String 和StringBuffer的区别 23 35、如何把一段逗号分割的字符串转换成一个数组? 24 36、数组有没有length()这个方法? String有没有length()这个方法? 24 37、下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d"; 24 38、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后? 25 39、下面的程序代码输出的结果是多少? 25 40、final, finally, finalize的区别。 27 41、运行时异常与一般异常有何异同? 27 42、error和exception有什么区别? 28 43、Java中的异常处理机制的简单原理和应用。 28 等等........

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值