今天,看到一个面试题:

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. MyBatis学习-使用Druid连接池将Maybatis整合到spring

    目录 前言 什么是Druid连接池 Druid可以做什么? 导入库包 连接oracle 连接mysql 导入mybatis 导入druid 导入spring-jdbc包 导入spring包 导入spr ...

  2. mycli工具mysql命令自动补全

    简介 MyCli 是一个 MySQL 的命令行客户端,可以实现自动补全和语法高亮.MyCli 也可用于 MariaDB 和Percona. 项目地址:http://mycli.net/ 安装 pip安 ...

  3. kernel 通知链

    原文链接: 深入理解linux网络技术内幕读书笔记(四)--通知链 概述 [注意] 通知链只在内核子系统之间使用. 大多数内核子系统都是相互独立的,因此某个子系统可能对其它子系统产生的事件感兴趣.为了 ...

  4. springboot整合websocket后打包报错:javax.websocket.server.ServerContainer not available

    项目整合了websocket以后,打包多次都没有成功,原来是报错了,报错内容如下: Error starting ApplicationContext. To display the conditio ...

  5. Alpha阶段项目复审(小菜鸡联盟)

    Alpha项目复审 小队:小菜鸡联盟 团队名称 项目名称 评价 排名 『S.L.N』 OnTime 优点:团队分工合理明确,每个成员有一定的开发经验,能用到自己较为熟悉的技术进行开发:在开发初期制定了 ...

  6. Git clone时出现fatal:the remote end hung up unexpectedly

    以HTTPS方式进行git clone时出现如下错误: 方法1:增大缓存 git config http.postBuffer 524288000 尝试无效: 方法2:配置git的最低速度和最低速度时 ...

  7. Java数据结构——红黑树

    红黑树介绍红黑树(Red-Black Tree),它一种特殊的二叉查找树.执行查找.插入.删除等操作的时间复杂度为O(logn). 红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点 ...

  8. .Net MongoDB批量修改集合中子集合的字段

    环境:.Net Core 3.1 (需要导入.Net MongoDB的驱动) 模型 /// <summary> /// 收藏 /// </summary> public cla ...

  9. JdbcTemplate jar包 下载

    我给了一个链接, 是jar download网站上的. 能上去的就可以下载. https://jar-download.com/maven-repository-class-search.php?se ...

  10. C++字符串与指针

    字符串初始化 在C++中基本数据类型并不包括string,string类型其实是一种类类型,通过STL函数库中的模板类basic_string 实例化得到. int main () { // stri ...