Java避坑指南:小心finally的执行逻辑

Java避坑指南:小心finally的执行逻辑

块是Java异常处理机制中的一个重要组成部分java if throwjava if throwJava避坑指南:小心finally的执行逻辑,它的执行逻辑有些特殊且容易让人困惑。下面从多个角度详细解析的执行逻辑。

java if throw

一、基本执行规则

1.1 块总是执行

核心原则:无论是否发生异常,块中的代码总是会执行(除非遇到极端情况)。

public class BasicFinally {
    public static void main(String[] args) {
        System.out.println("结果: " + testFinally());
    }
    
    public static String testFinally() {
        try {
            System.out.println("try块执行");
            return "try返回值";
        } catch (Exception e) {
            System.out.println("catch块执行");
            return "catch返回值";
        } finally {
            System.out.println("finally块执行");
        }
    }
}

输出:

try块执行
finally块执行
结果: try返回值

二、不同场景下的执行逻辑

2.1 正常执行(无异常)

public class NormalExecution {
    public static void main(String[] args) {
        System.out.println("开始测试");
        System.out.println("最终结果: " + normalCase());
    }
    
    public static String normalCase() {
        try {
            System.out.println("1. try块开始");
            String result = "正常结果";
            System.out.println("2. try块即将返回");
            return result; // 注意:这里不会立即返回!
        } finally {
            System.out.println("3. finally块执行");
        }
    }
}

输出:

开始测试
1. try块开始
2. try块即将返回
3. finally块执行
最终结果: 正常结果

java if throw

关键点:语句会先计算返回值并保存java if throw,然后执行块,最后才真正返回。

2.2 发生异常并被捕获

public class ExceptionCaught {
    public static void main(String[] args) {
        System.out.println("最终结果: " + exceptionCase());
    }
    
    public static String exceptionCase() {
        try {
            System.out.println("1. try块开始");
            if (true) throw new RuntimeException("测试异常");
            return "不会执行到这里";
        } catch (RuntimeException e) {
            System.out.println("2. catch块捕获异常: " + e.getMessage());
            return "异常处理结果";
        } finally {
            System.out.println("3. finally块执行");
        }
    }
}

输出:

1. try块开始
2. catch块捕获异常: 测试异常
3. finally块执行
最终结果: 异常处理结果

2.3 发生异常但未被捕获

public class ExceptionNotCaught {
    public static void main(String[] args) {
        try {
            uncaughtExceptionCase();
        } catch (Exception e) {
            System.out.println("主方法捕获异常: " + e.getMessage());
        }
    }
    
    public static void uncaughtExceptionCase() {
        try {
            System.out.println("1. try块开始");
            throw new RuntimeException("未捕获的异常");
        } finally {
            System.out.println("2. finally块执行(异常仍然会抛出)");
        }
    }
}

输出:

1. try块开始
2. finally块执行(异常仍然会抛出)
主方法捕获异常: 未捕获的异常

三、语句与的交互

3.1 中无语句

public class FinallyNoReturn {
    public static void main(String[] args) {
        System.out.println("测试1: " + testValueReturn());
        System.out.println("测试2: " + testReferenceReturn());
    }
    
    // 基本数据类型
    public static int testValueReturn() {
        int x = 10;
        try {
            return x; // 保存x的值(10)
        } finally {
            x = 20; // 修改x,但不影响已保存的返回值
            System.out.println("finally中x=" + x);
        }
    }
    
    // 引用数据类型
    public static StringBuilder testReferenceReturn() {
        StringBuilder sb = new StringBuilder("Hello");
        try {
            return sb; // 返回的是引用,不是副本
        } finally {
            sb.append(" World"); // 修改对象内容
            System.out.println("finally中sb=" + sb);
        }
    }
}

输出:

finally中x=20
测试1: 10
finally中sb=Hello World
测试2: Hello World

重要结论:

3.2 中有语句(️危险做法)

public class FinallyWithReturn {
    public static void main(String[] args) {
        System.out.println("情况1: " + testNormal());
        System.out.println("情况2: " + testException());
        System.out.println("情况3: " + testExceptionSuppressed());
    }
    
    // 正常执行,finally中return覆盖try中的return
    public static String testNormal() {
        try {
            System.out.println("try块执行");
            return "try的返回值";
        } finally {
            System.out.println("finally块执行");
            return "finally的返回值"; // 覆盖try的返回值
        }
    }
    
    // 异常情况,finally中return覆盖catch中的return
    public static String testException() {
        try {
            throw new RuntimeException("测试异常");
        } catch (Exception e) {
            System.out.println("catch块执行");
            return "catch的返回值";
        } finally {
            System.out.println("finally块执行");
            return "finally的返回值"; // 覆盖catch的返回值
        }
    }
    
    // finally中return会抑制异常
    public static String testExceptionSuppressed() {
        try {
            throw new RuntimeException("重要异常信息");
        } finally {
            System.out.println("finally执行,异常被抑制");
            return "异常被掩盖了";
        }
    }
}

输出:

try块执行
finally块执行
情况1: finally的返回值
catch块执行
finally块执行
情况2: finally的返回值
finally执行,异常被抑制
情况3: 异常被掩盖了

严重问题:中的会:

java if throw

覆盖try/catch中的返回值抑制异常(异常信息丢失!)四、总结

块的关键特性:

必然执行:除.exit()外,块总是执行执行时机:在try/catch的/throw之前执行返回值处理:基本类型:返回值的副本在前已保存引用类型:返回的是引用Java避坑指南:小心finally的执行逻辑,中的修改可能影响返回值危险操作:中的会覆盖之前的返回值中的会抑制异常中抛出异常会掩盖原始异常

公告:
1. 本站所有资源来源于用户上传和网络,如有侵权请联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系站长处理!
6. 本站不售卖代码,资源标价只是站长收集整理的辛苦费!如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
7. 站长QQ号码 2205675299

资源库 - 资源分享下载网 » Java避坑指南:小心finally的执行逻辑

常见问题FAQ

关于资源售价和售后服务的说明?
本站所有资源的标价均为本站收集资源的辛苦费,不代表资源本身的价值。软件是高智慧高价值的商品,不可能是白菜价。本站资源标价只是赞助费用,收取的赞助费仅用来维持本站的日常运营!毕竟收集整理资料需要投入云计算资源和站长大量的精力。
代码有没有售后服务和技术支持?
由于代码的运行具有不可预见性,本站不保证代码完整可运行,不提供技术支持和售后服务。 本站原创代码都是站长自己开发的,可以有偿提供技术支持服务。 网站里标明【亲测】的代码都是站长亲测过的,其他的代码由于精力有限,没有一一测试,不能保证代码就一定能够使用,更没有技术支持服务,下载前请自行斟酌。
有没有搭建服务?
由于搭建服务比较费时费力,所以本站除了原创代码外均不提供搭建服务。本站分享代码纯属兴趣爱好,不以盈利为目的,请勿咨询有没有搭建服务,谢谢理解。
链接地址失效了怎么办?
请带上资源链接地址联系客服,工作时间内我们看到后将第一时间回复。
关于解压密码
本站资源一般都没有加密,如果发现需要解压密码的,那么就输入 hao.35dc.com 试试。

发表评论

资源库,由老程序员细心甄别、精心筛选,只为提供优质的源码资源

关于我们 联系我们