当try、catch中有return时,finally中的代码会执行么?
今天,看到一个面试题:
try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
我们用代码来验证下:
    public static void main(String[] args) {
        System.out.println("我是输出结果a:" + test1());
    public static int test1() {
        int a = 5;
        try {
            System.out.println(a / 0);
            a = 10;
        } catch (ArithmeticException e) {
            System.out.println("我是catch中的a:" + a);
            return a = 20;// 程序执行到这时,a=20已经执行完,准备好返回结果了,发现有finally,则在去执行finally
        } finally {
            System.out.println("我是finally中未重定义的a:" + a);
            a = 30;
            System.out.println("我是finally中重定义过的a:" + a);
        }
        return a;
    }
运行结果:
我是catch中的a:5
我是finally中未重定义的a:20
我是finally中重定义过的a:30
我是输出结果a:20
从结果中可看出:即使catch中return了,finally中的代码还是会执行。但是有个问题,明明结果显示,经过finally代码的执行,a已经是30了,返回结果为什么还是20?
我们再执行另外代码:
     public static void main(String[] args) {
         System.out.println("我是输出结果a:" + test1());
     }
     public static int test1() {
         int a = 5;
         try {
             System.out.println(a / 0);
             a = 10;
         } catch (ArithmeticException e) {
             System.out.println("我是catch中的a:" + a);
             return a = 20;// 程序执行到这时,a=20已经执行完,准备好返回结果了,发现有finally,则在去执行finally
         } finally {
             System.out.println("我是finally中未重定义的a:" + a);
             a = 30;
             System.out.println("我是finally中重定义过的a:" + a);
             return a = 30;
         }
     }
运行结果:
我是catch中的a:5
我是finally中未重定义的a:20
我是finally中重定义过的a:30
我是输出结果a:30
我们会发现,如果finally中有return,结果会根据finally中的结果返回,如果finally中没有return,结果会按照catch的结果返回,但是不管怎么样,都是会执行finally的代码。
前面的例子是基本类型的,那我们看下引用类型是不是也这样:
     public static User getName1(){
         User user = null;
         try {
             user = new User("张三");
             throw new Exception();
         } catch (Exception e) {
             user = new User("李四");
             return user;
         } finally {
             user = new User("王五");
             //return user;
         }
     }
结果
User [name=李四]
再试下其他:
     public static User getName1(){
         User user = null;
         try {
             user = new User("张三");
             throw new Exception();
         } catch (Exception e) {
             user = new User("李四");
             return user;
         } finally {
             user = new User("王五");
             return user;
         }
     }
结果:
User [name=王五]
额。。。。。。引用类型类型好像也是这样的。
我们再看看:
     public static User getName2(){
         User user = null;
         try {
             user = new User("张三");
             throw new Exception();
         } catch (Exception e) {
             user.setName("李四");
             return user;
         } finally {
             user.setName("王五");
             //return user;
         }
     }
结果如下:
User [name=王五]
额。。。。好像不对啊,不应该是李四吗?
     public static User getName2(){
         User user = null;
         try {
             user = new User("张三");
             throw new Exception();
         } catch (Exception e) {
             user.setName("李四");
             return user;
         } finally {
             user.setName("王五");
             return user;
         }
     }
结果:
User [name=王五]
引用类型好像有问题啊。。。。
其实可以这么理解:执行完catch内的代码后,会把结果值暂时保存,然后执行finally中的代码,如果finally中没有return,则直接把保存的值返回。如果finally中有return,则值会被finally改变,再返回。
而如果finally中没有return,返回的值好像也有部分出乎我们的意料。可以这样理解吧,catch中的结果值会被final修饰,当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变
化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。
就那下面代码来说明:
 User u1 = new User("张三");
 User u2 = new User("李四");
 final User u3  = u1;
 u3 = u2;//这行代码会报编译错误
 System.out.println(u3);
 u1.setName("王五");
 System.out.println(u3);
第四行代码会报编译错误:The final local variable u3 cannot be assigned. It must be blank and not using a compound assignment
说明final修饰的不能改变引用对象,但是引用对象u1的值变化还是可以。
上面的代码执行下:
User [name=张三]
User [name=王五]
现在可以看出 上面的代码 user.setName("王五");和user = new User("王五"); 执行的结果为什么会不一样,因为setname改变的是引用所指向的对象的内容,是可以的。= new User("王五"); 是改变了引用指向,是不可以的。
当try、catch中有return时,finally中的代码会执行么?的更多相关文章
- Java中try、finally语句中有return时的执行情况 [转]
		原文:http://kingj.iteye.com/blog/1436761 在Java中当try.finally语句中包含return语句时,执行情况到底是怎样的,finally中的代码是否执行,大 ... 
- try catch finally ,try 中有return时怎么执行
- 如果try中有return那么finally中不要有return不然不会执行try中的return
		public class TryExer { public static void main(String[] args) { String test = test(); System.out.pri ... 
- trycatch之catch对捕获异常的处理及后续代码的执行的探索
		工作时,一直对try块中throw的异常对象,在catch中如何处理此异常,以及trycatchfinally完毕,程序是否就此停止还是继续运行很迷惑,于是参考网上的资料,自己写了些demo,去慢慢探 ... 
- java中的代码块执行顺序
		/* 代码块:在Java中,使用{}括起来的代码被称为代码块. 根据其位置和声明的不同,可以分为 局部代码块:局部位置,用于限定变量的生命周期. 构造代码块:在类中的成员位置,用{}括起来的代码.每次 ... 
- iframe中插入代码并执行
		最近有需求通过iframe插入代码.有蛮多方法,如下: 1 var iframe = document.getElementById('previewUrl'); 2 iframe.src = 'ab ... 
- try、finally代码块有无return时的执行顺序
		结论: 1.不管有没有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并 ... 
- 有return语句情况下,try-catch-finally的执行顺序
		重要结论: 1.不管有没有出现异常,finally块中代码都会执行 2.当try和catch中有return时,finally仍然会执行 3.finally是在return后面的表达式运算后执行的(此 ... 
- java中return在Try-Catch中的执行顺序
		我们知道return会结束此方法并返回指定值.以及在Try-catch-finally中无论try代码块中有没有异常finally中的代码时都会被执行的.但是如果return包含在try-catch- ... 
随机推荐
- 兼容ie9上传本地资源
			在ie9中上传文件出现问题,大多数的上传文件都采用new Formdata创建添加文件,在IE9中不支持Formdata对象操作,ie10是支持的.所以只能使用表单提交的方式进行操作. <for ... 
- jsp环境搭建及入门
			配置环境: 此处配置完成后startup.bat闪退,修改端口号重启后恢复正常 常见状态码: 200:一切正常 300/301:页面重定向(跳转) 404:资源不存在 403:权限不足(例如:访问a目 ... 
- Jmeter 常用函数(8)-  详解 __MD5
			如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 将指定的字符串 MD5 加密并返回,加 ... 
- 通过自定义资源扩展Kubernetes
			原文链接:通过自定义资源扩展Kubernetes 
- Eclipse导入项目后JSP页面出现报红
			Multiple annotations found at this line:- javax.servlet.jsp.JspException cannot be resolved to a typ ... 
- Prefrontal cortex as a meta-reinforcement learning system
			郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Nature Neuroscience, 2018 Abstract 在过去的20年中,基于奖励的学习的神经科学研究已经集中在经典模型上, ... 
- java安全编码指南之:基础篇
			目录 简介 java平台本身的安全性 安全第一,不要写聪明的代码 在代码设计之初就考虑安全性 避免重复的代码 限制权限 构建可信边界 封装 写文档 简介 作为一个程序员,只是写出好用的代码是不够的,我 ... 
- Excel—LEFT、RIGHT、MID函数提取不同位置的字段
			概述 函数方法不只是适用下述场景,主要目的是在不同业务场景中个人解决问题的思维方法: 下图中数据都为测试数据,不具备真实性! 场景一 数据库Task表中存储的实际任务id太长,但PC/移动端看到展示的 ... 
- 图数据库对比:Neo4j vs Nebula Graph vs HugeGraph
			本文系腾讯云安全团队李航宇.邓昶博撰写 图数据库在挖掘黑灰团伙以及建立安全知识图谱等安全领域有着天然的优势.为了能更好的服务业务,选择一款高效并且贴合业务发展的图数据库就变得尤为关键.本文挑选了几款业 ... 
- Vue + axios + SpringBoot 2实现导出Excel
			Vue + axios + SpringBoot 2实现导出Excel 1. 前端js代码-发送Http请求 /** * 文件下载 * @param url 下载地址 * @param fileNam ... 
