`
ZangXT
  • 浏览: 116438 次
  • 性别: 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  
加油,支持  

相关推荐

    涵盖了90%以上的面试题

    jdk1.5新特性 jdk1.7新特性 jdk1.8新特性 java语言有哪些优点? 同一个.java文件中是否可以有多个main方法 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 如何在main方法执行前输出”hello ...

    C#异常处理中try和catch语句及finally语句的用法示例

    主要介绍了C#异常处理中try和catch语句及finally语句的用法示例,finally语句的使用涉及到了C#的垃圾回收特性,需要的朋友可以参考下

    FileDownload.java

    代码用扫描工具扫出来问题,发现是try-catch-finally的另一种写法try-with-resource,发现这种写法优雅,代码量减少1/3(finally里面不用写close)这样就看的不那么臃肿了。因为上传,下载的时候有可能会创建input ...

    :sparkles:强大,优雅的微信小程序异步库:rocket:

    支持 ES2018 finally 特性 支持 TypeScript 开发 安装 你也可以直接把 dist 目录下的 wx-promise-pro.js 拷贝到项目里使用 $ npm i wx-promise-pro -S # or $ yarn add wx-promise-pro 初始化 import { promisifyAll...

    深入Java虚拟机(原书第2版).pdf【附光盘内容】

    3.5 java虚拟机中内置的安全特性 3.6 安全管理器和java api 3.7 代码签名和认证 3.8 一个代码签名示例 3.9 策略 3.10 保护域 3.11 访问控制器 3.11.1 implies()方法 3.11.2 栈检查示例 3.11.3...

    libex:从 code.google.complibex 自动导出

    C 的异常处理和 RAII 这个库为纯本地异常处理和 RAII 提供了一个小的语法 C 抽象。... try-in-catch-finally 结构比更常见的 try-catch-finally 具有更好的代数特性。 它还有助于特别高效的编译。 为什么?

    java 面试题(1)

    4. int 和 Integer 有什么区别5. String 和StringBuffer的区别6. 说出ArrayList,Vector, LinkedList的存储性能和特性7. &和&&的区别8. HashMap和Hashtable的区别9. final, finally, finalize的区别10. Overload和...

    python的教程.txt

    学习Python的异常处理机制,掌握try-except-finally语句的使用方法。 了解Python的文件操作,包括文件的打开、读写、关闭等。 学习Python的多线程和多进程编程,了解GIL(全局解释器锁)的概念和影响。 三、...

    Java学习笔记

    其中的代码语句论有没有异常都会被执行(因为finally子句的这个特性,所以一般将释放资源,关闭连接的语句写在里面)。 finally中的代码和try-catch中的代码冲突时,finally中的代码一定会被执行且会忽略try-catch中...

    leetcode题库-java-interview:Java研发基础相关

    finally finalize 反射 序列化与反序列化 transient 枚举 注解 JDK7新特性 JDK8新特性 JDK9新特性 JDK10新特性 运行时数据区 对象 OOM & SOF 内存模型 垃圾回收算法 垃圾收集器 内存分配与回收策略 类加载 参数优化 ...

    ASP.NET 2.0+SQL Server 2005全程指南-源代码

    2.6.2 用tryfinally清除异常 2.6.3 用trycatchfinally处理所有的异常 2.7 面向对象程序设计 2.7.1 成员 2.7.2 类的可访问性 2.7.3 构造函数和析构函数 2.7.4 封装 2.7.5 继承 2.7.6 多态 2.8 C#样语言...

    ActionScript开发技术大全

    8.3.1使用try…catch…finally语句 160 8.3.2throw语句主动抛出异常 162 8.3.3处理异常事件 163 8.4异常类型 163 8.4.1异常对象 164 8.4.2异常分类 164 8.4.3自定义异常类型 166 8.5小结 167 第3篇ActionScript3.0...

    轻松学C#(图解版)

    第三篇是应用技术篇,主要介绍的是异常处理、文件和流、委托、事件、Lambda表达式、命名空间、预处理器、程序集、运行时类型标识、反射、特性、泛型、LINQ和数据库开发等。 =======================================...

    Java经典面试题(答案解析)

    含基础篇,核心篇,框架篇,微服务篇 1.1.1 面向对象特征 封装,继承,多态和抽象 1、 封装 封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问...1.1.2 final, finally, finalize 的区别。。。

    Java开发常见问题总结.docx

    尽量使类具有高内聚低耦合特性。 优先考虑接口而不是实现,利用多态性。 适当使用设计模式提升代码复用和可维护性。 集合与数据结构: 根据需求选择合适的集合类型(List, Set, Map等)。 对于并发环境,使用线程...

    Visual.Basic.2010.&.NET4.高级编程(第6版)-文字版.pdf

    6.4.1 try、catch和finally关键字 270 6.4.2 throw关键字 271 6.4.3 抛出新的异常 272 6.4.4 exit try语句 273 6.4.5 嵌套的try结构 274 6.4.6 异常属性的使用 275 6.4.7 message属性 276 6.4.8 ...

    Wine配置便捷工具Vineyard-Wine.zip

    特性:Improved Prefix creation (see image above):You can now choose between creating a 64-bit or 32-bit prefix.A specific version of Wine can be selected to be used for the prefix.Installed versions ...

    高校门户网:大学生思想教育工作的新平台

    摘 要: 高校门户网的出现给大学生思想政治教育工作提供了新的契机和平台,研究从其基本功能特性出发,结合大学生思想政治教育工作的特点,对高校门户网兴起的原因进行横向的比较分析,论文提出高校思想政治教育在...

    最新最全Java面试题汇总

    最新Java面试题汇总 sleep() 和 wait() 有什么区别、final, finally, finalize的区别、面向对象的特征有哪些方面、ArrayList,Vector, LinkedList的存储性能和特性等诸多面试常见题目

    详解python with 上下文管理器

    Java 7 引入了能省去许多重复代码的 try-with-resources 特性,不用每回 try/finally 来释放资源(不便之处有局部变量必须声明在 try 之前,finally 里还要嵌套 try/catch 来处理异常)。比如下面的 Java 代码 try...

Global site tag (gtag.js) - Google Analytics