`
liujiawinds
  • 浏览: 139008 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

关于try catch finally执行顺序的一点疑问

    博客分类:
  • java
 
阅读更多
public class TryCatchOrder {
	public static void main(String[] args) {
		System.out.println(new TryCatchOrder().test());
	}
	static int i = 0;
	public int test() {
		try {
			System.out.println("抛出异常!");
			throw new Exception();
		} catch (Exception e) {
			System.out.println("进入catch块了!");
			return ++i;
			
		} finally {
			System.out.println("进入finally块了!");
			++i;
		}
	}
}

 输出为:1

 

 

public class TryCatchOrder {
	public static void main(String[] args) {
		System.out.println(new TryCatchOrder().test());
	}
	static int i = 0;
	public int test() {
		try {
			System.out.println("抛出异常!");
			throw new Exception();
		} catch (Exception e) {
			System.out.println("进入catch块了!");
			return ++i;
			
		} finally {
			System.out.println("进入finally块了!");
			return ++i;
		}
	}
}

 

输出为:2

 

经过调试,我发现,第一个例子里面的执行顺序是catch--finally--catch,第二个例子里面是catch--finally

还是有点没懂,为什么第一个例子的输出是 1。

 

 

 

 

3
5
分享到:
评论
2 楼 skzr.org 2013-06-20  
1. 顺序:肯定是先try,后catch,最后finally,这个是语言公理。
2. return:return ++i,调用后实际上是返回的i + 1,至于之后i的变化并不会影响到return ++i啊。
3. finally中return会发生什么事情:finally的return 实现了返回值压栈(覆盖之前的return压栈),同时函数调用结束,正常返回

给你一个代码自己看看就算是异常,finally都能吃掉他:
public class TryCatchOrder {
	public static void main(String[] args) {
		System.out.println(new TryCatchOrder().test());
	}
	static int i = 0;
	public int test() {
		try {
			++i;
			throw new IllegalArgumentException("明明发生了异常,怎么没有失败啊。。。");
		} finally {
			System.out.println("进入finally块了!");
			return ++i;
		}
	}
}
1 楼 jinnianshilongnian 2013-06-20  
建议你使用 javap -verbose TryCatchOrder  看看生成的字节码 就懂了,实际class字节码中是没有finally的。 它会把finally的代码复制到try和catch中


第一个的catch部分字节码
        20: ldc           #11                 // String 进入catch块了!
        22: invokevirtual #8                  // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
        25: getstatic     #12                 // Field i:I
        28: iconst_1
        29: iadd
        30: dup
        31: putstatic     #12                 // Field i:I
        34: istore_2 此处把return要返回的数据放入到了局部变量区的2部分存储
        35: getstatic     #2                  // Field java/lang/System.out:Ljav
a/io/PrintStream;
        38: ldc           #13                 // String 进入finally块了!
        40: invokevirtual #8                  // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
        43: getstatic     #12                 // Field i:I
        46: iconst_1
        47: iadd
        48: putstatic     #12                 // Field i:I
        51: iload_2 装载局部变量区的2部分返回 所以是1
        52: ireturn

即finally最终合并到catch中,如果是return 它会把返回的数据放入局部变量区,然后执行finally,最后把局部变量区的数据返回


第二个:

        20: ldc           #11                 // String 进入catch块了!
        22: invokevirtual #8                  // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
        25: getstatic     #12                 // Field i:I
        28: iconst_1
        29: iadd
        30: dup
        31: putstatic     #12                 // Field i:I
        34: istore_2
        35: getstatic     #2                  // Field java/lang/System.out:Ljav
a/io/PrintStream;
        38: ldc           #13                 // String 进入finally块了!
        40: invokevirtual #8                  // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
        43: getstatic     #12                 // Field i:I
        46: iconst_1
        47: iadd
        48: dup
        49: putstatic     #12                 // Field i:I
        52: ireturn

就是finally的return 覆盖了catch的,所以没有装载 istore_2,直接把finally运行的结果返回

相关推荐

    使用try-catch-finally处理异常

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

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

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

    try-catch-finally捕获异常

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

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

    在这个过程中,函数会将`try`或`catch`块中的`return`语句返回的值暂存起来,然后执行`finally`块。 如果在`finally`块中也有`return`语句,那么这个`return`值会覆盖之前暂存的值。也就是说,最终返回给调用者的值...

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

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

    try-catch-finally执行顺序验证

    try-catch-finally执行顺序验证(左边是.java文件,右边是.class文件) 提示: try、catch块内的return操作编译后会变成把return的值保存到变量var的操作。 总结: try、catch块内的return操作编译后会变成把return的值...

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

    在这个结构中,`try`块包含可能会抛出异常的代码,每个`catch`块分别捕获不同类型的异常,`finally`块则包含需要无论发生何种情况都必须执行的代码,如资源清理。 接下来,我们来探讨嵌套的`try-catch`块。当一个`...

    trycatch.zip

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

    C#中的try catch finally用法分析

    当在`try`块内的代码执行过程中出现异常时,控制权会立即转移到与之相关的`catch`块。如果没有异常发生,`catch`块的代码则不会被执行。 ```csharp try { // 可能抛出异常的代码 } ``` 2. `catch`块: `catch`块...

    java中try catch的用法

    // finally块总是会被执行,无论try-catch块中是否发生异常 // 通常用来释放资源等操作 } ``` #### 三、示例分析 根据题目提供的代码示例,我们来进行更深入的解析: ```java import java.io.*; public class ...

    C++异常处理技巧try/catch/throw/finally/exception

    通过合理地使用`try`、`catch`、`throw`和`exception`等关键字,开发者不仅能够编写更加可靠的代码,还能显著提升程序的可维护性和可读性。 #### 二、C++标准异常处理 ##### 1. 构造和析构中的异常抛出 在C++中,...

    C# 中的try catch finall 的使用方法

    在C#编程中,异常处理是程序健壮性的重要组成部分,`try-catch-finally`语句块就是C#提供的一种处理运行时错误的方式。它允许程序员在代码可能抛出异常的地方进行捕获并处理,确保即使在异常情况下,程序也能以一种...

    try-catch的用法和含义

    ### try-catch 的用法与含义详解 在编程过程中,异常处理是确保程序稳定性和健壮性的关键环节之一。`try-catch` 结构作为异常处理的核心机制,在各种编程语言中广泛采用,如 Java、C# 和 JavaScript 等。本文将深入...

    try-catch用法

    ### try-catch 用法详解 #### 一、引言 在编程中,错误处理是一项重要的任务,良好的错误处理机制可以提升程序的健壮性和用户体验。C# 中提供了 `try-catch` 结构来捕获并处理运行时可能出现的异常。通过本篇文章...

    try-catch-finally(处理方案示例).md

    无论try块中的代码执行是否成功,或者catch块是否被执行,finally块中的代码总是会被执行。这样可以确保程序的正常运作不会因为异常的发生而受到影响。 本文提供的示例演示了如何利用try-catch-finally结构来构建...

    java try…catch捕获异常的实例

    即使在`try`或`catch`块中有`return`语句,`finally`块中的代码也会被执行: ```java try { // 代码 } catch (ExceptionType1 e1) { // 处理 } catch (ExceptionType2 e2) { // 处理 } finally { // 清理资源,...

    java.try-catch-finally.md

    `finally`块是`try-catch`结构中可选的一部分,但当存在时,它的代码总是会在`try`块和任何`catch`块之后执行。无论是否发生了异常,`finally`块中的代码都会被执行。在示例代码中,`finally`块中的代码表示无论程序...

    java.try-catch-finally(解决方案).md

    try-catch-finally结构是Java中处理异常的基础,其基本用法包括:try块用于包裹可能出现异常的代码,catch块用于捕获并处理特定类型的异常,而finally块则用于执行无论是否发生异常都需要执行的代码,例如资源清理和...

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

    `finally`块包含在`try-catch`结构中,无论是否发生异常,`finally`块中的代码都会被执行。这通常用于清理资源,如关闭文件流、网络连接等。 ```java finally { // 清理代码,确保无论是否发生异常都会执行 } ``` ...

    C#异常处理终极指南:try-catch-finally的深度实践.pdf

    如果在try块中的代码执行过程中发生异常,控制权会立即跳转到相应的catch块。catch块则用于捕获和处理异常,它可以捕获特定类型的异常,也可以捕获所有异常。若需要处理多种不同类型的异常,可以使用多个catch块,并...

Global site tag (gtag.js) - Google Analytics