当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- ...
随机推荐
- Redis设计与实现——单机数据库的实现
数据库 服务器中的数据库 redisClient切换数据库 redis客户端默认目标数据库为0号数据库,可以通过SELECT命令来切换目标数据库. 客户端状态redisClient结构的db属性记录了 ...
- JS 时间获取 (常用)
/** * 获取几天之前日期 */ daysAgo(dayNum = 0) { let myDate = new Date() let lw = new Date(myDate - 1000 * 60 ...
- 《p5.js创意游戏编程》第一课:跳动的小球
准备:Hbuilder/vscode等可以编写网页的编辑器 如果想立刻上手也可以使用在线编译器p5.js官方在线编辑器,如果打不开也可以使用国内的一款在线编辑器jsrun编辑器,(第一课先使用jsru ...
- Vue企业级优雅实战-00-开篇
从2018.1.开始参与了多个企业的中台建设,这些中台的技术选型几乎都是基于 Spring Cloud 微服务架构 + 基于 Vue 全家桶的前端.我前后端架构及开发我几乎各占一半的精力,在企业级前端 ...
- idea 执行maven打包命令时,修改war包名称
- 焦大:逛网seo案例浅析
http://www.wocaoseo.com/thread-93-1-1.html 逛,发现喜欢.这或许是很多人上网的喜欢方式,我隐约记得白鸦在一次采访上说到现在人的购物方式,在淘宝上人们决定买一件 ...
- 深入了解v-model流程
v-model原理 vue中v-model是一个语法糖,所谓的语法糖就是对其他基础功能的二次封装而产生的功能.简单点说,v-model本身就是父组件对子组件状态以及状态改变事件的封装.其实现原理上分为 ...
- Unity调用PC摄像头
转载于Unity3d圣典里面,具体哪位大侠写的我忘咯. using UnityEngine; using System.Collections; public class CameraTest : M ...
- Unity资源引用问题
前几天做项目时,遇到一个奇怪的问题: 从一处复制了一个预制体,预制体上面还附有一个材质球,材质球上关联着另一张贴图. 将所有关联的东西,均Copy两份,然后关联成一个新的预制体,最后用项目内的读取内存 ...
- 深入了解Netty【四】IO模型
引言 IO模型就是操作数据输入输出的方式,在Linux系统中有5大IO模型:阻塞式IO模型.非阻塞式IO模型.IO复用模型.信号驱动式IO模型.异步IO模型. 因为学习Netty必不可少的要了解IO多 ...