今天,看到一个面试题:

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中的代码会执行么?的更多相关文章

  1. Java中try、finally语句中有return时的执行情况 [转]

    原文:http://kingj.iteye.com/blog/1436761 在Java中当try.finally语句中包含return语句时,执行情况到底是怎样的,finally中的代码是否执行,大 ...

  2. try catch finally ,try 中有return时怎么执行

  3. 如果try中有return那么finally中不要有return不然不会执行try中的return

    public class TryExer { public static void main(String[] args) { String test = test(); System.out.pri ...

  4. trycatch之catch对捕获异常的处理及后续代码的执行的探索

    工作时,一直对try块中throw的异常对象,在catch中如何处理此异常,以及trycatchfinally完毕,程序是否就此停止还是继续运行很迷惑,于是参考网上的资料,自己写了些demo,去慢慢探 ...

  5. java中的代码块执行顺序

    /* 代码块:在Java中,使用{}括起来的代码被称为代码块. 根据其位置和声明的不同,可以分为 局部代码块:局部位置,用于限定变量的生命周期. 构造代码块:在类中的成员位置,用{}括起来的代码.每次 ...

  6. iframe中插入代码并执行

    最近有需求通过iframe插入代码.有蛮多方法,如下: 1 var iframe = document.getElementById('previewUrl'); 2 iframe.src = 'ab ...

  7. try、finally代码块有无return时的执行顺序

    结论: 1.不管有没有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并 ...

  8. 有return语句情况下,try-catch-finally的执行顺序

    重要结论: 1.不管有没有出现异常,finally块中代码都会执行 2.当try和catch中有return时,finally仍然会执行 3.finally是在return后面的表达式运算后执行的(此 ...

  9. java中return在Try-Catch中的执行顺序

    我们知道return会结束此方法并返回指定值.以及在Try-catch-finally中无论try代码块中有没有异常finally中的代码时都会被执行的.但是如果return包含在try-catch- ...

随机推荐

  1. Redis设计与实现——单机数据库的实现

    数据库 服务器中的数据库 redisClient切换数据库 redis客户端默认目标数据库为0号数据库,可以通过SELECT命令来切换目标数据库. 客户端状态redisClient结构的db属性记录了 ...

  2. JS 时间获取 (常用)

    /** * 获取几天之前日期 */ daysAgo(dayNum = 0) { let myDate = new Date() let lw = new Date(myDate - 1000 * 60 ...

  3. 《p5.js创意游戏编程》第一课:跳动的小球

    准备:Hbuilder/vscode等可以编写网页的编辑器 如果想立刻上手也可以使用在线编译器p5.js官方在线编辑器,如果打不开也可以使用国内的一款在线编辑器jsrun编辑器,(第一课先使用jsru ...

  4. Vue企业级优雅实战-00-开篇

    从2018.1.开始参与了多个企业的中台建设,这些中台的技术选型几乎都是基于 Spring Cloud 微服务架构 + 基于 Vue 全家桶的前端.我前后端架构及开发我几乎各占一半的精力,在企业级前端 ...

  5. idea 执行maven打包命令时,修改war包名称

  6. 焦大:逛网seo案例浅析

    http://www.wocaoseo.com/thread-93-1-1.html 逛,发现喜欢.这或许是很多人上网的喜欢方式,我隐约记得白鸦在一次采访上说到现在人的购物方式,在淘宝上人们决定买一件 ...

  7. 深入了解v-model流程

    v-model原理 vue中v-model是一个语法糖,所谓的语法糖就是对其他基础功能的二次封装而产生的功能.简单点说,v-model本身就是父组件对子组件状态以及状态改变事件的封装.其实现原理上分为 ...

  8. Unity调用PC摄像头

    转载于Unity3d圣典里面,具体哪位大侠写的我忘咯. using UnityEngine; using System.Collections; public class CameraTest : M ...

  9. Unity资源引用问题

    前几天做项目时,遇到一个奇怪的问题: 从一处复制了一个预制体,预制体上面还附有一个材质球,材质球上关联着另一张贴图. 将所有关联的东西,均Copy两份,然后关联成一个新的预制体,最后用项目内的读取内存 ...

  10. 深入了解Netty【四】IO模型

    引言 IO模型就是操作数据输入输出的方式,在Linux系统中有5大IO模型:阻塞式IO模型.非阻塞式IO模型.IO复用模型.信号驱动式IO模型.异步IO模型. 因为学习Netty必不可少的要了解IO多 ...