Java try、catch、finally及finally执行顺序

本文详细解析Java中finally语句的作用,包括其在异常处理中的重要性,以及finally语句在不同场景下的执行顺序。通过实例演示,展示了finally语句在确保资源正确释放和异常处理中的应用,帮助读者理解和掌握Java中finally语句的使用方法。

1.为什么要用finally
先看一个没有finally的异常处理try-catch语句:
假设count为要使用到的资源,并且用完要求释放此资源。那么我们可以把释放资源的语句放到try-catch后执行,当前的程序不管是在执行完try语句块还是catch语句块,都会顺序执行到下面释放资源的语句。

int count = 0;  //初始化资源
try{
  count++;
  if(count == 1) throw new Exception("Exception in try");
}catch(Exception e){
  System.out.println("catch block");
}
count = 0; //释放资源

但是,如果在try或catch中有多条return语句,那么在每条return语句之前,都要先执行释放资源的语句:

public void f() throws Exception {
 int count = 0;  //初始化资源
 try{
   doSomething;
   statementMayCauseException;  //可能会抛出异常的语句,若异常没有被catch,则直接抛出,也不会执行到try-catch下面的语句
   doSomething;
   if(count == 1) throw new Exception1("E1 in try");
   if(count == 2) throw new Exception2("E2 in try");
 }catch(Exception1 e){
   count = 0; //释放资源
   throw e;  //再次把异常抛出,让上一级捕获。此时将不会执行catch外的语句,所以要先释放资源
 }catch(Exception2 e){
  count = 0; //释放资源
  return; //返回了,也不会执行catch外的语句,所以要先释放资源
 }
 count = 0; //释放资源
}

这样,就需要在每一个可能返回的地方,以及每一个可能出现异常而导致程序跳转的地方,考虑如何释放资源,导致复杂和冗余。

所以,需要finally语句。
把资源释放或状态还原的代码放到finally块中,可以保证在try和catch语句执行完后,一定会执行finally语句块,而不用考虑各种复杂的跳转情况。

int count = 0;
try{
 count++;
 if(count == 1)throw new Exception();
}catch(Exception e){
}finally{
 count = 0;
}

2.finally什么时候执行
finally在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");
   //return "finally";    
  }  
 }  
 public static String test1() {  
  System.out .println("return statement");  
  return "after return";  
 }  
}

结果:
try block
return statement
finally block
after return

分析:
1.try语句块,return test1(),则调用test1方法
2.test1()执行后返回”after return”,返回值”after return”保存在一个临时区域里
3.执行finally语句块。若finally语句有返回值,则此返回值将替换掉临时区域的返回值
4.将临时区域的返回值送到上一级方法中。

说明:
如果catch块有异常向外抛出,finally也一定会执行,两者互不干涉。

    public static void tryDemo(){
        try {
            String str = null;
            System.out.println("try block");
            str.length();
        } catch (Exception e) {
            System.out.println("catch block");
            /////
//          System.exit(0);//若调用了此方法,就不会执行finally了
            /////
            String str = null;
            str.length();//此代码段有异常抛出,但是不影响finally的执行,两者分别执行
            ////
            System.out.println("after catch block");
        } finally {
            System.out.println("finally block");
        }
    }

输出:
这里写图片描述

关于finally,除非调用system.exit()让程序退出或断电等因素致使程序中止,否则,无论任何因素,finally块都一定会执行!!

<think>首先,用户的问题是:我想理解Java中多个try-catch-finally块嵌套时的执行顺序。请问Java 多层嵌套的 try catch finally 执行顺序详解。 系统指令要求: - 所有行内数学表达式使用$...$格式(但在这个上下文中,可能不涉及数学表达式,所以可能不需要)。 - 独立公式使用$$...$$并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 参考提供的引用内容。 提供的引用是关于异常处理的,特别是try-catch-finally块: - [^1]:讨论在可能失败的操作前检查,以及finally块的性能影响。 - [^2]:讨论异常传递、资源释放和异常类型匹配。 - [^3]:finally块的基本用法。 - [^4]:try-catch-finallytry-with-resource的基本介绍。 用户的问题是关于多层嵌套的try-catch-finally块的执行顺序。所以,我需要基于Java的异常处理机制来解释执行顺序。 关键点: - 在Java中,try块包含可能抛出异常的代码。 - catch块处理特定类型的异常。 - finally块总是执行,无论是否有异常,除非JVM退出(如System.exit())。 - 当有嵌套时,执行顺序取决于异常是否被抛出和处理。 执行顺序规则: 1. 当try块中的代码执行时,如果没有异常,执行finally块(如果有),然后继续后续代码。 2. 如果有异常抛出: - 匹配catch块:如果找到匹配的catch块,执行它。 - 然后执行finally块。 - 如果没有匹配的catch块,异常传播到外层try块(如果有),或者到调用者。 3. finally块总是执行,即使在catch块中有return或抛出异常。 对于嵌套的try-catch-finally: - 考虑内层和外层。 - 执行顺序:从内层开始,向外层传播。 示例结构: ```java try { // Outer try block try { // Inner try block } catch (Exception e) { // Inner catch block } finally { // Inner finally block } } catch (Exception e) { // Outer catch block } finally { // Outer finally block } ``` 执行顺序: - 如果没有异常:执行内层try块,然后内层finally块,然后外层try块(如果有后续代码),然后外层finally块。 - 如果内层try块抛出异常: - 如果内层catch块匹配并处理了异常:执行内层catch块,然后内层finally块,然后继续外层代码。 - 如果内层catch块不匹配或没有catch块:异常传播到外层,执行内层finally块,然后外层catch块(如果匹配),然后外层finally块。 - 如果finally块中有return或抛出异常,它会覆盖catch块中的行为。 关键规则: - finally块总是执行,无论是否有异常。 - 如果finally块中有return,它会覆盖trycatch块中的return。 - 异常传播:如果异常没有被catch块处理,它传播到外层。 现在,构建回答: - 结构清晰:逐步解释。 - 使用中文。 - 生成相关问题。 - 引用提供的段落:自然地添加引用标识。 引用内容: - [^1]提到finally块总是会执行,即使没有异常发生。 - [^2]讨论异常传递和资源释放。 - [^3]描述finally块的基本用法。 - [^4]解释try-catch-finally机制。 在回答中,我可以引用这些来支持我的解释。 回答大纲: 1. 介绍try-catch-finally的基本概念。 2. 解释单个try-catch-finally执行顺序。 3. 扩展到多层嵌套。 4. 提供示例代码和解释。 5. 讨论常见陷阱和最佳实践。 6. 生成相关问题。 最后,添加相关问题。</think>### Java 多层嵌套 try-catch-finally 执行顺序详解 在 Java 异常处理中,`try-catch-finally` 块用于管理代码执行中的异常和资源清理。当多个块嵌套时,执行顺序遵循严格的规则:**从最内层向外层逐级处理,且 `finally` 块总是执行,无论是否发生异常**。以下我将逐步解释执行顺序,并提供示例代码和常见场景分析。执行顺序的核心原则基于 Java 语言规范(JLS
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值