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

关于Java finally的一些思考

    博客分类:
  • java
阅读更多
先来看一段关于Java fiannlly 的定义, 百度过来的:

finally通常和try/catch语句一起使用,确保了无论是否发生异常,finally里面的代码都会被执行。



关于这个定义,我想起来之前遇到的一个面试题,如果在try语句中return了,finally里面的代码还会执行么?

    public static void main(String[] args) {
        try {
            System.out.println("try block");
            
            return;
        } finally {
            System.out.println("finally block");
        }
    }

打印结果为:
try block
finally block

这说明了什么? 即使是在try语句中return了,finally里的代码依然会被执行到。

那么我就想到另一个问题,finally里的代码究竟是在return前执行的,还是在return后执行的?

我设计了这样一段代码:
public class Test {

    public static void main(String[] args) {
        System.out.println(test());
    }
    
    public static String test() {
        try {
            System.out.println("try block");
            
            return test1();
        } finally {
            System.out.println("finally block");
        }
    }
    
    public static String test1() {
        System.out.println("return statement");
        
        return "after return";
    }
}


究竟是先执行return 还是先执行finally呢?

结果是这样的:
try block
return statement
finally block
after return

可见是先调用了return的方法,然后才调用finally的代码。

这里就产生了一个悖论,既然某个方法已经return了,为什么还有代码继续执行呢?


我们看看产生的会编码:
public class Test {
  
  // Method descriptor #6 ()V
  // Stack: 1, Locals: 1
  public Test();
    0  aload_0 [this]
    1  invokespecial java.lang.Object() [8]
    4  return
      Line numbers:
        [pc: 0, line: 2]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: Test
  
  // Method descriptor #15 ([Ljava/lang/String;)V
  // Stack: 2, Locals: 1
  public static void main(java.lang.String[] args);
     0  getstatic java.lang.System.out : java.io.PrintStream [16]
     3  invokestatic Test.test() : java.lang.String [22]
     6  invokevirtual java.io.PrintStream.println(java.lang.String) : void [26]
     9  return
      Line numbers:
        [pc: 0, line: 5]
        [pc: 9, line: 6]
      Local variable table:
        [pc: 0, pc: 10] local: args index: 0 type: java.lang.String[]
  
  // Method descriptor #25 ()Ljava/lang/String;
  // Stack: 2, Locals: 2
  public static java.lang.String test();
     0  getstatic java.lang.System.out : java.io.PrintStream [16]
     3  ldc <String "try block"> [34]
     5  invokevirtual java.io.PrintStream.println(java.lang.String) : void [26]
     8  invokestatic Test.test1() : java.lang.String [36]
    11  astore_1
    12  getstatic java.lang.System.out : java.io.PrintStream [16]
    15  ldc <String "finally block"> [39]
    17  invokevirtual java.io.PrintStream.println(java.lang.String) : void [26]
    20  aload_1
    21  areturn
    22  astore_0
    23  getstatic java.lang.System.out : java.io.PrintStream [16]
    26  ldc <String "finally block"> [39]
    28  invokevirtual java.io.PrintStream.println(java.lang.String) : void [26]
    31  aload_0
    32  athrow
      Exception Table:
        [pc: 0, pc: 12] -> 22 when : any
      Line numbers:
        [pc: 0, line: 10]
        [pc: 8, line: 12]
        [pc: 12, line: 14]
        [pc: 20, line: 12]
        [pc: 22, line: 13]
        [pc: 23, line: 14]
        [pc: 31, line: 15]
  
  // Method descriptor #25 ()Ljava/lang/String;
  // Stack: 2, Locals: 0
  public static java.lang.String test1();
     0  getstatic java.lang.System.out : java.io.PrintStream [16]
     3  ldc <String "return statement"> [41]
     5  invokevirtual java.io.PrintStream.println(java.lang.String) : void [26]
     8  ldc <String "after return"> [43]
    10  areturn
      Line numbers:
        [pc: 0, line: 19]
        [pc: 8, line: 21]
}


仔细看这段:
     0  getstatic java.lang.System.out : java.io.PrintStream [16]
     3  ldc <String "try block"> [34]
     5  invokevirtual java.io.PrintStream.println(java.lang.String) : void [26]
     8  invokestatic Test.test1() : java.lang.String [36]
    11  astore_1
    12  getstatic java.lang.System.out : java.io.PrintStream [16]
    15  ldc <String "finally block"> [39]
    17  invokevirtual java.io.PrintStream.println(java.lang.String) : void [26]
    20  aload_1
    21  areturn



也就是说,经过编译以后,代码变成了先调用test1,并存储返回值,然后调用finally里面的代码,最后才return。


这段代码似乎没有什么现实意义,不过还是可以对java程序的理解有一定的帮助。
分享到:
评论
1 楼 leero 2011-02-21  
很好,讲的不错、

相关推荐

    java 编程入门思考

    引言 1. 前提 2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD-ROM 8. 源代码 9. 编码样式 10. Java版本 ...1.11 Java和因特网 ...1.13 Java还是C++?...附录E 关于垃圾收集的一些话 附录F 推荐读物

    Java程序设计教程,电子教案,实例源程序,思考练习参考答案

    3. **异常处理**:Java提供了异常处理机制,通过try-catch-finally语句块来捕获和处理运行时错误,保证程序的健壮性。 4. **函数与方法**:函数是代码的复用单元,方法是类中的函数。理解参数传递、方法重载和...

    java基础巩固,思考 java-se java基础巩固,思考,从底层到精通 测试一个

    4. **异常处理**:学习如何使用try-catch-finally语句块进行异常处理,以及标准的Java异常类层次结构。 5. **集合框架**:掌握ArrayList、LinkedList、HashSet、HashMap等集合类的使用,理解它们之间的区别以及何时...

    [探秘Java:如何像计算机科学家一样思考].(唐尼).张平.扫描版.pdf

    《探秘Java:如何像计算机科学家一样思考》这本书由唐尼撰写,张平翻译,旨在帮助读者以计算机科学家的视角理解和掌握Java编程语言。通过深入阅读这本书,我们可以挖掘出一系列重要的Java编程和计算机科学思维的知识...

    java面向对象编程课后思考题答案

    以上是Java面向对象编程的一些基本概念,通过解决孙卫琴女士教程中的课后思考题,学习者可以更好地理解和应用这些知识。解答集"answer"应详细阐述了这些问题的解题思路和实现方法,对于深入学习和复习Java面向对象...

    《Java面向对象编程》思考题及答案PDF

    这些知识点是《Java面向对象编程》一书的核心内容,通过阅读书中的思考题及答案,可以帮助读者巩固理论知识,提升实际编程能力。对于初学者来说,理解并熟练运用这些概念是掌握Java编程的关键步骤。

    java program 思考

    同时,Java的异常处理机制(try-catch-finally)使得程序在遇到错误时能够优雅地处理,保证程序的稳定运行。 总的来说,“Java program 思考”涵盖了从基础的面向对象编程到类的多样性、继承性等多个重要方面。深入...

    JAVA课程总复习

    5. **异常处理**:讲述如何使用try-catch-finally语句块来捕获和处理程序运行时可能出现的错误。 6. **IO流**:讲解输入/输出流的基本概念,包括字节流和字符流,以及缓冲区、对象序列化等相关知识。 7. **多线程**...

    《java编程思想》_java编程思想_java编程思想_ThinkinginJava_mileefx_

    "Thinking in Java",直译为“思考Java”,鼓励读者不仅仅是学习语法,而是要理解Java的设计理念和背后的思考方式,从而提升编程能力。 Java编程思想的核心概念包括: 1. **面向对象编程**:Java是一种完全面向...

    140个Java源码实例

    3. **异常处理**:Java提供了强大的异常处理机制,源码中会有try-catch-finally结构的示例,帮助你理解如何捕获和处理程序运行时可能出现的错误。 4. **集合框架**:Java集合框架包括ArrayList、LinkedList、...

    关于java学习总结.docx

    - **多角度思考:** 不同的编程思想可能导致不同的实现方式,了解并分析这些差异有助于提升个人的技术水平。 #### 二、业务逻辑与应用场景 **1. 业务知识的重要性:** - **具体领域:** 每个企业的业务都有其独特...

    java习题-多选题

    - **异常处理**:Java中的try-catch-finally语句块用于捕获和处理运行时异常,throw和throws关键字用于抛出异常。 - **多线程**:Java内置了Thread类和Runnable接口,通过实现这些来创建并管理多线程。同步机制如...

    java编程题目 有答案

    4. 异常处理:在Java中,异常处理是通过try、catch、finally关键字和自定义异常来实现的,这对于编写健壮的代码至关重要。 5. 设计模式:虽然设计模式可能不会直接在初级编程题目中出现,但了解并应用一些常见的...

    Java异常处理和最佳实践(含案例分析).pdf

    Java异常处理并不是一个简单的事情,不仅初学者很难理解,甚至一些有经验的开发者也需要花费很多时间来思考如何处理异常。阿里巴巴Java开发规范中有15条关于异常处理的说明,但是这些说明告诉了我们应该怎么做,却...

    Thinking Java Programming Code

    4. **异常处理**:通过try-catch-finally语句块,Java提供了强大的异常处理机制,有助于编写健壮的代码。 5. **集合框架**:Java集合框架是处理对象数组的关键,包括List、Set、Queue和Map接口,以及ArrayList、...

    自考Java语言程序设计(一)课后习题及答案

    5. **异常处理**:Java的异常处理机制使得程序更加健壮,习题中可能会有处理try-catch-finally块以及throw和throws关键字的题目。 6. **数组**:数组是存储同类型数据的集合,理解和使用数组是解决复杂问题的基础。...

    Java编程100例_java100例_

    在异常处理方面,实例将展示如何使用try-catch-finally块来捕获和处理运行时错误,以提高程序的健壮性。此外,文件输入输出也是编程中常见的一环,这些实例会教你如何读写文本文件,以及如何处理二进制文件。 集合...

    java 各种学习资料

    异常处理是Java编程中的关键部分,它通过try-catch-finally语句块来捕获和处理程序运行时可能出现的错误。正确处理异常可以提高程序的健壮性。 Java集合框架是处理数据结构和集合的工具,包括List(如ArrayList和...

    <java面向对象编程>孙卫琴课后答案

    Java面向对象编程是Java...以上是Java面向对象编程的一些核心概念和关键知识点,通过理解和掌握这些内容,可以为深入学习Java编程打下坚实的基础。而孙卫琴老师的课后答案集则可以帮助学习者更好地理解并应用这些知识。

    合工大Java作业

    7. **实验报告**部分可能要求学生对完成的每个作业进行总结,分析问题解决思路,反思编程实践中遇到的困难以及解决方案,这有助于培养学生的思考和表达能力,提升编程素养。 通过这份作业,学生不仅能够强化Java...

Global site tag (gtag.js) - Google Analytics