`
ZangXT
  • 浏览: 118016 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

finally的小特性

阅读更多

        try/catch/finally语句下,finally子句是肯定会执行的。但是很多人做不同的测试,却得出了不同的结论。

具体的原理最好是去看《深入java虚拟机》,里面对jsr、ret等几个指令做了详细的说明。这里不深入分析,而仅仅是从表现形式上看一下finally的特征。

代码:

  

/*
 * author: Zang XT
 */

public class TestFinal {
    public static void main(String[] args) {
        System.out.println("test1:" + testFinal1());
        System.out.println("test2:" + testFinal2());
        System.out.println("test3:" + testFinal3());
        System.out.println("test4:" + testFinal4());
    }

    static int testFinal1() {
        int i = 1;
        try {
            return i;
        } finally {
            System.out.println("in testFinal1():finally 肯定会被执行的!");
            i = 48;
        }
    }

    static String testFinal2() {
        String str = "try";
        try {
            return str;
        } finally {
            System.out.println("in testFinal2():finally 肯定会被执行的!");
            str = "finally";
        }
    }

    static StringBuilder testFinal3() {
        StringBuilder build = new StringBuilder("try ");
        try {
            return build;
        } finally {
            System.out.println("in testFinal3():finally 肯定会被执行的!");
            build.append("finally");
            build = new StringBuilder("你猜我是谁!");
        }
    }

    static String testFinal4() {
        try {
            return "return in try";
        } finally {
            System.out.println("in testFinal4():finally 肯定会被执行的!");
            return "return in finally";
        }
    }
}

 

 

输出是:

in testFinal1():finally 肯定会被执行的!

test1:1

in testFinal2():finally 肯定会被执行的!

test2:try

in testFinal3():finally 肯定会被执行的!

test3:try finally

in testFinal4():finally 肯定会被执行的!

test4:return in finally

     结论很明显,finally的语句确实执行了,而且肯定是在方法return之前执行的,而且,如果finally中有return语句的话,方法直接结束。这里需要注意的只有一点:在try中的return语句会将返回结果值压栈,然后转入到finally子过程,等到finally子过程执行完毕之后(没有return),再返回。
下面具体看4个例子:
      在testFinal1()中,return i;会将结果i的值,也就是1压入栈。即使在finally中将i修改了(i=48),也不回对已经压入栈里的1造成任何影响。
      在testFinal2()中,return str;将str的内容压入栈,比如我们假设str的内容为0x108(只是一个地址值),通过这个地址值我们能找到"try",那栈里的内容就是0x108。执行str = "finally",这时候str这个变量的内容可能变为0x237了,这是串"finally"的地址。方法调用结束后,返回的是什么?return时压入栈里的0x108。所以在打印结果时,我们打印的是通过0x108找到的字符串"try"。
      在testFinal3()中,return 压栈的是build这个变量的值,比如是0x3579,通过这个值我们可以找到StringBuilder对象。finally语句块中对这个对象的内容进行了修改。build = new StringBuilder("你猜我是谁!");让build变量指向了一个新的对象,这时候build的值可能是0x4579了。但是,别忘了,原来的StringBuilder对象仍然在0x3579处,而我们压栈的正是0x3579啊!方法返回后,我们得到的返回值0x3579,通过这个引用值找到相应的StringBuilder对象,所以打印的结果是test3:try finally。
      在testFinal4()中,finally有return语句,直接返回,方法结束。
      为什么不同的人有不同的结论?关键是没有正确理解压栈的是什么东西。其实初学java的时候,如果理解了变量是什么,并区分引用和对象本身就不会得到错误的结论了。再有,如果理解java中,方法调用都是采用传值模式的话,这里也就类似的可以明白了。
分享到:
评论
7 楼 lin_style 2009-11-17  
跟windows的SEH略有不同。SEH里return和finally在一起,finally会覆盖return压栈的值,然后返回
6 楼 adminsun 2009-10-02  
来看看,传值和传址还是晕晕的 
5 楼 蔡华江 2009-09-18  
看一次,忘一次;
忘一次,看一次。
4 楼 leisure 2009-09-18  
压栈是什么时候进行的?
执行return 语句时候?
3 楼 constant 2009-09-16  
thank you...
2 楼 本来不想注册 2009-08-04  
Very Good Article
1 楼 yexin218 2009-07-09  
加油,支持  

相关推荐

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

    这个特性使得`finally`成为处理资源清理,如关闭文件流、数据库连接等操作的理想选择。在讨论`finally`语句的执行时机时,我们需要理解Java的异常处理机制。 Java的异常处理机制由`try-catch-finally`结构组成。`...

    jvm特性与java特性

    4. 异常处理:Java提供了一套完整的异常处理机制,通过try、catch、finally等语句,能够优雅地处理程序运行中可能出现的异常情况。 5. 跨平台性:Java程序能够在任何安装了JVM的平台上运行,这使得Java应用的部署和...

    jdk7新特性jdk8新特性

    在try语句中声明的资源会在finally块中自动关闭,无论是否发生异常。这适用于实现了`AutoCloseable`(包括`Closeable`)接口的对象。例如: ```java try (InputStream is = new FileInputStream("xx"); ...

    C++ 中try finally关键字详解

    这是 `finally` 关键字的核心特性,确保资源清理逻辑总是能够被执行,比如关闭文件、释放内存等。 以下是一个简单的例子: ```cpp #include void doSomething() { std::cout 块中" ; // 模拟可能出现异常的...

    深入理解Python特性_1592298155816.pdf,深入理解python特性pdf,Python

    同时,Python还支持finally子句,确保在任何情况下都能执行某些清理操作。 Python的模块化设计也是其强大之处。通过import语句,我们可以导入其他Python文件作为模块,实现代码的复用和组织。了解如何创建和使用...

    Java异常处理新特性

    Java 异常处理新特性 Java 异常处理新特性是在 Java7 中引入的一种新的异常处理机制,它提供了一种更加简洁、可靠的方式来处理资源使用异常。这种机制称为 try-with-resources,实际上是自动调用资源的 close() ...

    java try…catch…finally捕获异常的实例

    在Java编程语言中,异常处理是一项关键特性,用于在程序执行过程中处理可能出现的错误或异常情况。`try-catch-finally`结构是Java提供的一种优雅的处理异常的方式,确保了程序在遇到错误时能正常运行并有机会清理...

    JDK 7 新特性小结实例代码解析

    JDK 7 是Java开发的一个重要版本,引入了许多新的特性和改进,提升了开发效率和代码的可读性。以下是对这些新特性的详细说明: 1. **Switch 支持 String 做参数** 在JDK 7之前,switch语句只支持基本数据类型(如...

    try catch finally的执行顺序深入分析

    这是`finally`块的核心特性,它用于确保某些代码无论在何种情况下都会被执行,例如关闭文件流、释放资源等。即使在`try`或`catch`块中有`return`语句,`finally`块仍然会先执行。在这个过程中,函数会将`try`或`...

    java第七章高级类特性.rar

    Java语言的高级类特性是其强大且灵活的关键因素之一,这些特性使得开发者能够构建出高效、可维护的代码。在“第七章高级类特性”中,我们主要会探讨以下几个核心概念: 1. **抽象类与接口**:抽象类是不能被实例化...

    JVM高级特性与最佳实践(第2版)源代码.zip

    - 异常链、自定义异常、finally块的重要性。 - 线程安全问题:了解死锁、活锁、饥饿、竞态条件等,并学习如何避免。 9. **JVM优化实践**: - 根据应用特性选择合适的JVM版本和配置。 - 通过监控和日志分析进行...

    讲解Java编程中finally语句的基本使用方法

    `)总是会被执行,这展示了`finally`的关键特性。 在异常处理中,`finally`的主要作用是确保必要的清理工作得以完成,如关闭文件流、网络连接或其他资源。在没有`finally`的情况下,如上面提到的`WithoutFinally`类...

    finally 一定会执行(实例代码)

    总结来说,`finally`块的特性在于其确定性。无论`try`块中的代码是否抛出异常,或者`catch`块是否捕获到异常,`finally`块的代码都将无条件执行。这是确保资源释放、日志记录等关键操作得以完成的关键机制。在编写...

    Powershell中Finally语句用法示例

    在Powershell编程中,`Finally`语句是异常处理机制的一个重要组成部分,它用于确保在发生异常或者脚本被用户中断(如通过Ctrl+C)时,...在实际编程中,我们应当充分利用这一特性来编写更稳定、可靠的Powershell脚本。

    JDK 7新特性的PPT(本届JAVAONE 2010的演讲材料)

    这个特性允许在`try`块中声明资源,这些资源会在`finally`块中自动关闭,避免了手动管理资源,减少潜在的资源泄露: ```java try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) { // ...

    Java核心技术(卷2):高级特性(原书第9版)

    3. **异常处理**:Java异常处理是程序错误处理的关键部分,包括`try-catch-finally`块、`throw`和`throws`关键字,以及自定义异常的创建。理解如何有效利用异常处理可以提高代码的健壮性。 4. **集合框架**:Java...

    C#6.0新特性Demo

    C#6.0是.NET Framework的重要更新,引入了一系列新的特性和语法糖,旨在提升开发效率和代码可读性。以下是对这些新特性的详细解析: 1. **Null条件操作符(?.)** C#6.0引入了“?.”操作符,用于安全地访问可能...

    ( Java核心技术 卷II 高级特性(原书第9版).zip )PDF 高清版

    书中会讲述如何正确使用try-catch-finally语句,以及如何自定义异常。 8. **JVM内部机制**:理解JVM的工作原理对于优化代码性能至关重要。书中将探讨内存模型、垃圾收集、类加载机制等内容,以及如何通过JDK工具...

    C#语言特性学习(快速上手)

    此外,还有`finally`块,无论是否发生异常,这段代码都会执行,通常用来释放资源。 文件及数据流技术在C#中用于读写磁盘上的文件。你可以使用`FileStream`类与磁盘交互,`StreamReader`和`StreamWriter`用于文本...

Global site tag (gtag.js) - Google Analytics