java里的try...catch...finally的三角恋关系众多程序员必然是不陌生的。但是他们三者再加上一个return的话,就会难倒一大片人吧。以前就对这个知道这个问题,没系统的总结一下,结果今天女神把我问倒了。。so。。。。

下面就分别看一下吧!

case1:finally语句+try中有return:在执行到return的时候,会先执行finally里面的内容,然后再执行行try中的return。

@SuppressWarnings("finally")
static void test() {
int x = 1;
try {
logger.info("try.....");
return;
} finally {
++x;
logger.info("finally....."); }
}

输出:

try.....
finally......

case2:case1+finally里也有return语句:try代码块中的return不执行,即在try中遇到return的时候,会先执行finally里面的内容(包括finally里面的return语句)。

public static void main(String[] args) {
logger.info(TryCatchDemo.test1());
} @SuppressWarnings("finally")
static int test1() {
int x = 1;
try {
logger.info("try.....");
return x;
} finally {
x = x + 1;
logger.info("finally.....");
return x;
}
}

输出:

2014-04-08 16:39:23,311 INFO  [TryCatchDemo.java:23] : try.....
2014-04-08 16:39:23,347 INFO [TryCatchDemo.java:27] : finally.....
2

好了,接下里是今天的重头戏了,就是偶被女神难倒的问题。

Case3:Important 我在try里return了某一个值,但是我在finally里对这个值进行了修改,那try块里返回的值是什么?先看代码。

    public static void main(String[] args) {
logger.info(TryCatchDemo.test2());
}
@SuppressWarnings("finally")
static int test2() {
int x = 1;
try {
logger.info("try.....");
return x;
} finally {
++x;
logger.info("finally.....");
}
}

该代码会输出什么呢?按照我们正常的理解的话,先执行try里的语句,遇到return时候就去执行finally里的语句,然后修改了x的值为2,最后try里的return返回。

可是结果呢?

2014-04-08 16:45:37,548 INFO  [TryCatchDemo.java:62] : try.....
2014-04-08 16:45:37,551 INFO [TryCatchDemo.java:66] : finally.....
2014-04-08 16:45:37,552 INFO [TryCatchDemo.java:16] : 1

结果输出的是1。说明finally里面对要返回的值进行修改,没有反应到最终的结果上去!如果是自己发现的问题的话,估计就到时为止了,下次记住就行了,可问这个问题的可是女神啊。so,屌丝决定看下这段代码编译出来的class对应的字节码,看虚拟机内部是如何执行的。

系统的环境是centos 6.4 x64

jdk环境见下图:

我们用javap -verbose TryCatchFinally >> TyrCatchFinally.txt 来把class文件字节码信息重定向到文件中。(javap是jdk自带的反编译工具命令)

这里主要是看test2部分的反编译字节码:

public int test2();
flags: ACC_PUBLIC
Code:
stack=2, locals=4, args_size=1
0: iconst_1 将整型常量1压入栈顶
1: istore_1 //将栈顶的整数出栈,并存入局部变量区的第2个变量
2: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
5: ldc #7 将字符串常量压入栈顶 // String try.....
7: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: iload_1 //将局部变量区的第2个变量压入栈
11: istore_2 //将栈顶的整数出栈,并存入局部变量区的第3个变量
12: iinc 1, 1
15: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
18: ldc #9 // String finally.....
20: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: iload_2
24: ireturn
25: astore_3
26: iinc 1, 1
29: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
32: ldc #9 // String finally.....
34: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
37: aload_3
38: athrow

可惜。。。字节码没看懂啊。。。唉。。。留帖,以后再说吧。唉。。

try...catch...finally...return的四角恋的更多相关文章

  1. try catch finally return之间的关系

    一.try catch finally return之间的关系: 正在写dsoFramer的时候,同事突然说面试的时候问的一个问题,catch和return那个先执行,我瞬间迷茫了,然后整理了整理,稍 ...

  2. 异常 try catch finally return 执行关系 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. try catch finally return运行顺序

    首先让我们搞懂两组概念:try catch finally和return 1.try catch finally 首先说try catch, (1)try语句 ,try语句用来包围可能出现异常的代码片 ...

  4. Java_try,catch,finally return之间的执行顺序

    以往认为函数只要执行到return语句便会返回结果并终止,然而这时错误的,因为这存在特例. 掌握下面几条原则就可以完全解决“当try.catch.finally遭遇return”的问题. 原则:1.f ...

  5. java try catch finally return执行

    public static int testBasic(){ int i = 1; try{ i++; System.out.println("try block, i = "+i ...

  6. 当try、catch中有return时,finally中的代码会执行么?

    今天,看到一个面试题: try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 我们用代码来验证下: public static void mai ...

  7. java-try catch中return在finally之前 还是之后执行

    finally语句在return语句执行之后return返回之前执行的. finally块中的return语句会覆盖try块中的return返回. 如果finally语句中没有return语句覆盖返回 ...

  8. C#:在catch中return,会执行finally吗?

    本文转自 vipxiaotian(CSDN) 请参考下面一段简单的语句块: 1:  try2:  {3:      throw new Exception("new exception&qu ...

  9. try catch finally return

    public override bool Start(IServerConfig config) { bool flag = true; listenSocket = new Socket(Liste ...

随机推荐

  1. javacript没有多维数组只能模拟?

    为什么说javacript没有多维数组只能模拟?但是我看到是可以实现多维数组的啊!这是为什么呢?下面我们来实验下. <!DOCTYPE html> <html lang=" ...

  2. qsort函数辅助函数compare函数的编写

    qsort的第四个参数,辅助函数compare的关于不同排序对象的不同写法: 一.对int类型数组排序 ]; int compare(const void *a, const void *b) { r ...

  3. shell脚本调试方法

    我们开启了 Shell 脚本调试系列文章,先是解释了不同的调试选项,下面介绍如何启用 Shell 调试模式. 写完脚本后,建议在运行脚本之前先检查脚本中的语法,而不是查看它们的输出以确认它们是否正常工 ...

  4. install font

    哪些字体包含国际音标呢? 在微软的Windows与Office的2000或以上版本中分别带有Lucida Sans Unicode和Arial Unicode MS两种字体(以下分别简称LSU和AUM ...

  5. JSONModel解析数据成Model

    转自:http://blog.csdn.net/smking/article/details/40432287 JSONModel, Mantle 这两个开源库都是用来进行封装JSON->Mod ...

  6. sql身份证号查人数

    select a.*,b.item_name from (select sum(buy_num) num,nqh from (select substr(a.embed_dis_province,1, ...

  7. js去除字符串中所有html标签及&nbsp符号

    近日在做项目的时候,经常会在页面上处理一些数据.结果发现自己js掌握的并不是很好.那就在这里记录js的点点滴滴吧. 1. 去除字符串中的 html 标签 function delHtmlTag(str ...

  8. 三层交换机配置说明(华为S5700设置三个网段互通)

    1.配置Switch # 创建VLAN <HUAWEI> system-view[HUAWEI] sysname Switch[Switch] vlan batch 10 20 30# 配 ...

  9. Chapter 2 Open Book——9

    When I was finished with that, I took my book bag upstairs. Before starting my homework, I changed i ...

  10. windows 装 centos

    windows下压缩一下空间 直接装centos 找到分配给linux的/boot目录,然后修改grub/menu.lst文件,更换一下位置即可