`
liujiawinds
  • 浏览: 131926 次
  • 性别: 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执行顺序验证

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

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

    try、catch、finally、return 执行顺序超详细讲解,包看包会。

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

    首先执行try,如果有异常执行catch,无论如何都会执行finally,当有return以后,函数就会把这个数据存储在某个位置,然后告诉主函数,我不执行了,接下来你执行吧,所以函数就会推出

    C#中的try catch finally用法分析

    主要介绍了C#中的try catch finally用法,以实例形式分析了try catch finally针对错误处理时的不同用法,具有一定的参考借鉴价值,需要的朋友可以参考下

    try-catch-finally.js:一个很小的库,用于在JavaScript中更灵活地捕获错误

    try-catch-finally.js 843字节库,可在JavaScript中更灵活地捕获错误。内容注意事项按名称捕获可能不起作用按类型捕获在跨框架/过程中不起作用错误被消耗测验 安装 浏览器< script src =" try-catch-finally.js ...

    trycatchfinaly

    3. 但是如果有 finally块的话,那么,finally 几乎是必定会执行的,但是这里有一个先后顺序的问题,应该是 finally 块和 打印异常堆栈将会在另外一个线程之中执行,所以 打印的顺序就很有意思了。 4. 如果在try或者...

    VB.Net常用语法

    在一个try………end try 过程中可以使用catch与finally两个中的一 个,或者两个一起用, 二:Protected, private, Public 封装控制 这三个关键字一般放在语句最前面,而会置于overloads与Overrides的 后面...

    C#异常处理总结及简单实例

    C# 异常处理时建立在四个关键词之上的:try、catch、finally 和 throw。 1、try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。 2、catch:程序通过异常处理程序捕获异常。catch ...

    C#异常处理的技巧和方法

    finally是监听程序是否在try或者catch中执行 下面列举的是try执行的语句是一个异常错误的情况 下面列举的是try执行语句是一个正确的情况 异常类的一个继承顺序图,异常类中的属性列表 catch中的表达式的几种...

    10道Java常见异常面试题含答案(很全)

    Java异常处理是Java编程中一个非常重要的部分,它允许程序在遇到错误或异常情况时采取适当的行动...finally语句块:无论是否发生异常,finally语句块中的代码都将被执行。通常用于清理资源,例如关闭文件或数据库连接。

    实验五 Java异常处理实验.docx

    实验五 Java异常处理实验.docx

    java面试题之try中含return语句时代码的执行顺序详解

    主要介绍了关于java中的一道面试题,这套题就是在try中含return语句时代码的执行顺序,这个问题看似简单,却暗藏杀机啊!文中通过一个个例子详细介绍了其中玄机,需要的朋友可以参考学习,下面来一起看看吧。

    Java异常处理.md

    - 当代码执行过程中出现如除数为零的`ArithmeticException`等错误时,Java会立即转至相应的catch块进行异常处理,如输出错误信息并打印堆栈跟踪。 2. **finally块的使用**: - 不论try块中的代码是否抛出异常,...

    Java异常发生时程序的执行顺序

     5.finally段的代码无论是否发生异常都会执行。  6.在一个try语句块中,基类异常的捕获语句不可以写在子类异常捕获语句的上面。  看一个例子:   /** * @author Lansine *

    Java异常处理细节分析

    Java的异常处理机制是其一大特色。本文对异常处理机制做了简要介绍,重点分析了try-catch-finally语句执行流程,举例说明了“突然中止”对异常处理过程的影响。

    Java面试问题带答案40道.docx

    答:异常处理是指在程序执行过程中遇到错误时进行处理的机制。Java中使用try-catch语句来捕获异常并进行处理。 7. 什么是Java中的泛型? 答:泛型是Java中一种参数化类型的概念,允许在编译时期检查类

    Java高级程序设计:第8章-异常处理.pptx

    会使用 try-catch-finally 处理异常 方法声明异常 抛出异常 自定义异常类 语法错误, 运行期错误, 逻辑错误 语法错误: 没有遵循语法规则导致的错误。 运行期错误: 程序运行时,运行环境发现一个不可能执行的操作。 ...

    最新NIIT考试题目

    try{ if( sel==0 ){System.out.println("no Exception "); return;} else if( sel==1 ){ int i=0; int j=4/i;} } catch( ArithmeticException e ) { System.out.println("Catch "); } catch( Exception e ...

    java中的语句运算符数组.docx

    • 控制语句:if-else、switch、while、do-while等。这些语句用于控制程序的执行流程,根据条件...• 异常处理语句:try-catch-finally等。这些语句用于处理程序运行过程中可能出现的异常情况,例如除以零、空指针等。

    javascript 异常处理使用总结

    使用try..catch..finally语句来处理异常 js代码在执行过程中如果出现异常,会手动创建一个异常类对象,该异常类对象将被提交给浏览器,这个过程称为“抛出异常”。当浏览器接收到一场对象时,会寻找能处理这一异常的...

Global site tag (gtag.js) - Google Analytics