`
darxin
  • 浏览: 8013 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

return & finally

JVM 
阅读更多

Creative Commons License

【在一次CSDN论坛中的讨论 时,看到了ZhangXT 的一篇文章:finally是肯定会执行的! 本文是为其做的注。】

 

与大多数高级语言一样,Java通过return语句实现函数的带值返回功能。如: 

public static String test(){
    String str = "Hello world";
    return str;
}

 
与C/C++的处理方式不同,Java在编写代码时,不允许return语句之后还是其它语句存在。如:

public static String test(){ 
    String str = "Hello world"; 
    return str; 
    str = "Hello world!"; // 编译错误。 
} 

 

但是这种语法规则又不是绝对的。如:

public static String test(){ 
    String str = "try"; 
    try { 
        return str; 
    }finally { 
        str = "finally"; 
    } 
} 

 
此例编译可以通过,并且函数的返回值为字符串“try”。我们知道finally子句在try子句之后执行,上例从表面上看,“return str;”语句在“str = "finally";”语句之前被执行。
如果Java语法不允许return语句之后存在其它语句,那么为什么上例在编译时能通过?
如果因为某种原因上例编译通过并能够运行,那么为什么这个函数会返回字符串“try”而不是“finally”呢?

 

finally子句总是被执行

有人会说,如果try子句中存在return语句的话,finally子句不会被调用。这种论断是错误的。如下例:

class Test { 
    public static void main(String[] args) throws Exception { 

        System.out.println(test()); 
    } 

    public static String test() { 
        String str = "try"; 
        try { 
            return str; 
        } finally { 
            System.out.println("finally called"); 
        } 
    } 
} 

 
上例的调用结果如下:

finally called
try

 

其结果可以证明,无论try子句是否存在return语句,finally子句总是被调用。

 

return操作总是在最后执行

再看一下上文提到的函数:

public static String test(){ 
    String str = "try"; 
    try { 
        return str; 
    }finally { 
        str = "finally"; 
    } 
} 

 

问题的实质在于
如果在try子句中存在return语句,JVM做了两件事:
1. 记住最后一个return语句所处代码位置上需要返回的变量值;
2. 将这个值放在函数调用过程的最后返回。


也就是说,上例中“return str;”一句,函数调用过程中会记录下此时str变量的值,这个值就是函数需要返回的值;当函数调用结束后,即finally子句结束后,将刚才记录下 来的值返回。
因此上述代码的返回值是“try”而不是“finally”。 其本质上可以用下面的代码表示:

public static String test(){ 
    String tmp;  // 声明一个“用于返回数据的变量” 
    String str = "try"; 
    try { 
        tmp = str; // 将需要返回的值赋值给该变量 
    }finally { 
        str = "finally"; 
    } 
    return tmp; // 将“用于返回数据的变量”的值返回 
} 

 

 

总是最后一个return语句在起作用

如果在try子句与finally子句中都有return语句,哪一个起作用呢?最后一个。如代码:

public static String test(){ 
    String str = "try"; 
    try { 
        return str; 
    }finally { 
        str = "finally"; 
        return str; 
    } 
} 

 

上例函数的返回值为“finally”,因为是最后一个return语句在起作用。
其本质上可以用下面的代码表示:

public static String test(){ 
    String tmp;  // 声明一个“用于返回数据的变量” 
    String str = "try"; 
    try { 

        tmp = str; // 将需要返回的值赋值给该变量 
    }finally { 

        str = "finally"; 
        tmp = str; // 将需要返回的值赋值给该变量 
    } 
    return tmp; // 将“用于返回数据的变量”的值返回 
} 

 

 

return语句返回的是变量的值而不是对象的内容

关于变量的值与对象的内容之间的关系 ,这里不再多说。需要记住的是,return语句返回的是变量的值,与对象的内容无关。如:

public static StringBuilder test(){ 
    StringBuilder build = new StringBuilder("try "); 
    try{ 
        return build; 
    } finally { 
        build.append("finally"); 
        build = new StringBuilder("new value"); 
    } 
} 

 

上例中“return build;”一句记录下此时build变量的值(引用对象的地址值),之后第7句对build变量的重新赋值已经无法影响函数的返回值,但是第6句修改 了build变量所指对象的内容。因此上例的返回值,其所指对象的内容为“try finally”而不是另一个内容为“new value”的新对象。

上述代码本质上可以用下面的代码表示:

public static StringBuilder test(){ 
    StringBuilder tmp;  // 声明一个“用于返回数据的变量” 
    StringBuilder build = new StringBuilder("try "); 
    try{ 
        tmp = build; // 将需要返回的值赋值给该变量 
    } finally { 
        build.append("finally"); 
        build = new StringBuilder("new value"); 
    } 
    return tmp; // 将“用于返回数据的变量”的值返回 
} 

 

© 丑小鸭技术专栏 | 查看原文

 

 

分享到:
评论

相关推荐

    java 中finally语句块与return的执行关系

    Java 中 finally 语句块与 return 的执行关系 Java 中的 finally 语句块是用于保证无论出现什么情况,一定要执行的代码块。在 try-catch-finally 结构中,finally 语句块的执行顺序是非常重要的。下面我们来详细...

    try-catch-finally-return-in-finally.rar_return

    标题 "try-catch-finally-return-in-finally.rar_return" 提到了 `try-catch-finally` 结构与 `return` 语句的交互,这涉及到程序执行流程的关键方面。 `try` 块是用来包含可能会抛出异常的代码。如果在 `try` 块中...

    try-finally-return-in-finally.rar_return

    标题“try-finally-return-in-finally.rar_return”暗示了我们正在讨论`return`语句如何与`finally`块内的`return`交互。在JavaScript中,如果`try`块或`finally`块包含`return`语句,程序的行为可能会变得复杂。 ...

    Java finally语句到底是在return之前还是之后执行?

    3. 即使在`finally`块中也有`return`语句,`finally`块中的代码将被执行,然后返回值会被覆盖。这意味着`finally`块的`return`总是会覆盖`try`或`catch`块中的`return`。 现在让我们深入源码层面来进一步理解这个...

    浅谈Java中return和finally的问题

    在Java编程语言中,`return` 语句和 `finally` 语句的相互作用是一个重要的概念,尤其是在处理异常处理时。`finally` 语句块通常用于确保某些代码无论是否发生异常都会被执行,而 `return` 语句用于提前结束方法并...

    Jungle68#-#[Java] try catch finally,try里有return,finally还执行么?1

    Condition 3: try中有异常,try-catch-finally里都没有return ,finally 之后有个returntry中有异常以后,根据

    try、catch、finally、return 执行顺序.doc

    try、catch、finally、return 执行顺序详细讲解 try、catch、finally、return 执行顺序是 Java 编程语言中的一种 exception 处理机制,用于处理程序中的异常情况。下面我们来详细讲解 try、catch、finally、return ...

    浅析Python中return和finally共同挖的坑

    本文主要给大家介绍了在Python中return和finally共同存在的坑,以及填坑经验,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 初识 return 相信每一个用过Python函数的童鞋, 肯定会用过return...

    Java语言finally语句详解,finally到底是在return之前还是之后执行.zip

    Java语言finally语句详解,finally到底是在return之前还是之后执行.zip

    Java中finally和return的关系实例解析

    Java中finally和return的关系实例解析 Java中finally和return的关系实例解析是Java编程语言中一个重要的知识点。finally语句是Java语言中的一种特殊语句,它用于释放资源、关闭文件、关闭网络连接等操作。return...

    Java中finally块执行与return关系深度剖析

    Java finally语句到底是在return之前还是之后执行?Java finally执行深度剖析,具体看这篇博文:http://blog.csdn.net/lanxuezaipiao/article/details/16922895,这是里面相关的源码,欢迎大家下载使用。

    try~catch~finally中关于return的问题

    在Java的异常机制中,如果finally中含有return语句,则try和catch中的return语句将会被JVM忽视

    Java的throw和return

    3. **finally中的return**:如果`finally`块中也包含了一个`return`语句,则该`return`语句会覆盖`try`块或`catch`块中的`return`语句。这意味着最终返回给调用者的值将是`finally`块中`return`语句指定的值。 综上...

    浅谈Java finally语句到底是在return之前还是之后执行(必看篇)

    从结果可以看到,finally 块中的 return 语句会覆盖 try 块中的 return 语句,try 块中的 return 语句就不能返回了。 finally 语句是在 try 的 return 语句执行之后,return 返回之前执行的。 finally 块中的 ...

    finally结构的注意点(一)

    1. **返回值**:如果 `finally` 块包含 `return` 语句,那么它将覆盖 `try` 或 `catch` 块中的任何 `return` 语句。这意味着最后的返回值是由 `finally` 块决定的。 2. **跳转语句**:即使使用了 `break`、`...

    try-catch-finally捕获异常

    return x / y; } ``` 六、程序设计 本实验的程序设计主要包括两个部分:main方法和myDevide()方法。main方法用于调用myDevide()方法,并输出结果。myDevide()方法用于执行除法运算,并捕获和处理异常。程序的设计...

    Java异常处理中同时有finally和return语句的执行问题

    由于`finally`块的`return`语句位于`try`块的`return`之后,所以`finally`块的`return`会覆盖`try`块的`return`,导致最终返回的`s`值是"b"。 对于一个方法来说,`return`语句有两个主要功能:一是返回方法的计算...

    使用try-catch-finally处理异常

    即使在`try`或`catch`块中有return语句,`finally`块的代码也会被执行。 5. **多层嵌套** 你还可以在`try-catch-finally`结构内部嵌套另一个`try-catch-finally`结构,以处理更复杂的情况。这种方式使得异常处理...

    关于Java中的try-catch-finally语句和return

    第一:return语句并不是函数的终出口,如果有finally语句,这在return之后还会执行finally(return的值会暂存在栈里面,等待finally执行后再返回)  第二:finally里面不建议放return语句,根据需要,return语句...

Global site tag (gtag.js) - Google Analytics