`
ajaxgo
  • 浏览: 18777 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

关于java中,try/catch执行的问题

阅读更多

今天无意中,同事发现了一个有趣的现象,首先来看一下以下代码:

java 代码会发现,18行加载了一下变量b中的值,所以,其实,在执行代码的第8行时,并不是执行return,而只是往内存中存储变量b的值。

  1. public class Test {   
  2.     private static int todo() {   
  3.         int b=1;   
  4.         try{   
  5.             int a=2/0;   
  6.         } catch(Exception e) {   
  7.             System.out.println("in catch");
  8.             return 1;   
  9.         } finally {   
  10.             System.out.println("in final");   
  11.         }   
  12.         return 2;   
  13.     }   
  14.     /**  
  15.      * @param args  
  16.      */  
  17.     public static void main(String[] args) {   
  18.         System.out.println(todo());   
  19.   
  20.     }   
  21. }  

此时,运行结果为
in catch
in final
1

看到这里,少部分人已经开始不明白了,我们继续看另一则代码(请注意细小的差别):

java 代码
  1. public class Test {      
  2.     private static int todo() {      
  3.         int b=1;      
  4.         try{      
  5.             int a=2/0;      
  6.         } catch(Exception e) {      
  7.             System.out.println("in catch");   
  8.             return b;      
  9.         } finally {      
  10.             System.out.println("in final");      
  11.         }      
  12.         return 2;      
  13.     }      
  14.     /**    
  15.      * @param args    
  16.      */     
  17.     public static void main(String[] args) {      
  18.         System.out.println(todo());      
  19.      
  20.     }      
  21. }     

此时,运行结果依旧是
in catch
in final
1

但是通过单步执行,会发现,两种代码的执行顺序有少许差别

第一种代码的try/catch单步执行顺序为
7->10->8

第二种代码的try/catch单步执行顺序为
7->8->10->8

这里我们对其进行了研究,从中间码入手,首先来分别看看两者的中间码:

上述第一块代码的中间码
  1. 11  ldc <String "in catch"> [22]   
  2. 13  invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]   
  3. 16  getstatic java.lang.System.out : java.io.PrintStream [16]   
  4. 19  ldc <String "in final"> [30]   
  5. 21  invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]   
  6. 24  iconst_1   
  7. 25  ireturn  

可以发现,明显的执行顺序,1行把装入字符串转入内存,2行打印,4行在把字符串装入内存,5行再打印,7行返回

上述第二块代码的中间码
  1. 13  ldc <String "in catch"> [22]   
  2. 15  invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]   
  3. 18  iload_0 [b]   
  4. 19  istore_3   
  5. 20  getstatic java.lang.System.out : java.io.PrintStream [16]   
  6. 23  ldc <String "in final"> [30]   
  7. 25  invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]   
  8. 28  iload_3
  9. 29  ireturn  

 

以上的过程,分析下中间码,还是可以理解的,但是非常非常让人奇怪的是,如下的代码(请还是注意不同的细节)

java 代码
  1. public class Test {         
  2.     private static int todo() {         
  3.         int b=1;         
  4.         try{         
  5.             int a=2/0;         
  6.         } catch(Exception e) {         
  7.             System.out.println("in catch");      
  8.             return b;         
  9.         } finally {  
  10.             b=3;       
  11.             System.out.println("in final");         
  12.         }         
  13.         return 2;         
  14.     }         
  15.     /**      
  16.      * @param args      
  17.      */        
  18.     public static void main(String[] args) {         
  19.         System.out.println(todo());         
  20.         
  21.     }         
  22. }        

此时运行结果照样是
in catch
in final
1

单步执行结果是 7->8->10->11->8
想不通的是,根据单步执行,在finally里对b进行了修改,但是,返回的仍旧是1

再来看看这个代码的中间码:

第三个代码的中间码
  1. 13  ldc <String "in catch"> [22]   
  2. 15  invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]   
  3. 18  iload_0 [b]   
  4. 19  istore_3   
  5. 20  iconst_3   
  6. 21  istore_0 [b]   
  7. 22  getstatic java.lang.System.out : java.io.PrintStream [16]   
  8. 25  ldc <String "in final"> [30]   
  9. 27  invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]   
  10. 30  iload_3   
  11. 31  ireturn  

因为,其实我没怎么学过汇编,只是初步的分析了
3行加载b的地址,4行在地址3储存b的值(此时地址3的值为1),5行加载一个常量,6行把常量存入b的地址(此时b的值为3),10行加载地址3的值,最后返回值。
不知道这样的解释是否合理,也请,希望能够得到一个对于try./catch块执行问题的通俗答案,谢谢!

分享到:
评论
1 楼 Qieqie 2007-08-31  
参考某New版某贴:《在finally赋值为什么无效》
http://www.iteye.com/topic/79092

然后本贴可以结贴了。

相关推荐

    java try…catch嵌套捕获异常的实例

    总结来说,`try-catch`嵌套在Java中用于更精细化的异常处理,允许我们针对不同类型的异常执行不同的恢复策略。通过这种方式,我们可以编写更健壮、更易维护的代码,确保程序在面对错误时能够优雅地处理并继续运行。

    java中try catch的用法

    ### Java中try-catch的用法详解 #### 一、基本概念 在Java编程语言中,`try-catch`结构是一种用于处理程序运行时可能出现的异常情况的重要机制。通过使用`try-catch`块,开发者可以更加精细地控制程序的行为,并...

    java try…catch捕获异常的实例

    `try-catch`块是Java异常处理的核心部分,它允许程序员在代码可能出现问题的地方进行异常捕获和处理,避免程序因未预期的错误而崩溃。下面我们将详细讨论`try-catch`捕获异常的实例。 首先,`try`块是包含可能抛出...

    try_catch_finally异常处理java

    本文将深入探讨Java中的`try-catch-finally`语句块,以及它们在异常处理中的作用。 首先,`try`块是异常处理的起点。在这个代码段中,我们通常会放置可能会抛出异常的代码。当Java执行到可能抛出异常的代码行时,...

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

    总结来说,`try-catch-finally`结构是Java中处理异常的关键工具,它允许开发者优雅地处理错误,保持程序的健壮性,同时确保必要的清理工作得以执行。通过正确使用这些结构,可以提高代码的可读性和可维护性。

    Java中try、catch的使用方法

    "Java中try、catch的使用方法" 本文主要介绍了Java中try、catch的使用方法,通过实例代码详细地介绍了try、catch的使用方法,对大家的学习或工作具有一定的参考借鉴价值。 try-catch语句的语法格式为:try{ //代码...

    try-catch的用法和含义

    `try-catch` 结构作为异常处理的核心机制,在各种编程语言中广泛采用,如 Java、C# 和 JavaScript 等。本文将深入探讨 `try-catch` 的基本概念、语法结构及其应用场景。 #### 一、`try-catch` 的基本概念 `try-...

    try-catch-finally捕获异常

    try-catch-finally语句是Java语言中一种常用的异常处理机制,当程序在执行过程中出现异常时,可以使用try-catch-finally语句来捕获和处理异常。下面将详细介绍try-catch-finally语句的使用方法和注意事项。 一、try...

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

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

    trycatch.zip

    本示例中的"trycatch.zip"文件内容就是展示了如何在Golang中模拟`try...catch`和`try...catch...finally`。 Golang的核心错误处理方式是通过返回错误值。通常,函数会返回一个错误值,如果在执行过程中遇到问题,就...

    使用try-catch-finally处理异常

    `finally`块是可选的,无论`try`和`catch`块中的代码是否抛出异常,`finally`块里的代码都会被执行。这通常用于资源清理,如关闭文件流、网络连接等。即使在`try`或`catch`块中有return语句,`finally`块的代码也会...

    Java软件开发实战 Java基础与案例开发详解 10-3 使用try和catch捕获异常 共10页.pdf

    根据给定文件的信息,我们可以提炼出关于Java异常处理的关键知识点,特别是如何使用`try`和`catch`来捕获和处理异常。 ### 10.3 使用try和catch捕获异常 #### 10.3.1 try和catch的基础概念 - **try**:尝试执行的...

    Java try catch finally异常处理组合详解

    Java try catch finally异常处理组합是Java语言中的异常处理机制,用于捕获和处理程序中的异常。下面对try catch finally异常处理组合进行详细的介绍。 try catch组合: try catch组合是Java中最基本的异常处理...

    Springboot全局异常捕获及try catch区别解析

    当代码执行到try语句块中时,如果出现了异常,Java虚拟机会将其捕获并抛出到catch子句中,在catch子句中可以进行异常处理和错误信息的返回。try catch语句可以捕获到各种类型的异常,包括运行时异常和检查异常。 而...

    java基础知识-try-catch的使用

    try块中包含可能会产生异常的代码,当try块内的代码发生异常时,程序会立即跳转到与异常类型相匹配的catch块进行处理。 在catch块中,你可以编写适当的处理逻辑来处理特定类型的异常。每个catch块可以捕获不同类型...

    关于java try()的括号中代码含义(实现Closeable接口)(csdn)————程序.pdf

    在传统的`try-catch-finally`中,`finally`块用于确保在执行完`try`块后,即使有异常抛出,资源也能被正确关闭。然而,这需要手动调用`close()`方法,如文件流、网络连接等。 Java 7引入的`try-with-resources`语句...

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

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

    Java异常处理的四大金刚:try、catch、finally和throw的深度解析

    在Java中,`try`、`catch`、`finally`和`throw`这四个关键字构成了异常处理的核心。 #### `try`关键字 `try`关键字用于标记一段可能抛出异常的代码块。这部分代码被称为`try`块,它包含了可能会引发异常的操作。...

    java异常处理.ppt

    Java 异常处理 Java 异常处理是 Java 编程语言中的一种错误处理机制,它允许...Java 异常处理是 Java 编程语言中的一种错误处理机制,通过使用 try 块、catch 块和 finally 块,可以捕获和处理运行时的异常情况。

    Try…Catch使用小结

    总之,Try…Catch 机制是异常处理的核心,它帮助我们优雅地处理预期之外的问题,保证程序的健壮性。正确地使用 Try…Catch 结构,结合自定义异常和资源管理策略,可以提高代码的稳定性和可维护性。

Global site tag (gtag.js) - Google Analytics