zoukankan      html  css  js  c++  java
  • 【Java】finally用法

    一.概述

    1. 本文说明Java中finally的用法和可能遇到的坑
    2. finally的目的是保证代码被执行,但也会存在不执行的情况
    3. finally 代码块的原理是复制 finally 代码块的内容,分别放在 try-catch 代码块所有正常执行路径以及异常执行路径的出口中。
      所以不管是是正常还是异常执行,finally都是最后执行的。

    二. finally会执行的情况

    1.有catch(无异常)

    try {
        System.out.println("try execute");
        
    } catch (RuntimeException e) {
        System.out.println("catch execute");
        
    } finally {
        System.out.println("finally execute");
    }
    
    输出
    try execute
    finally execute
    

    3.有catch(try异常)

    try {
        System.out.println("try execute");
        throw new RuntimeException("try Exception");
    
    } catch (Exception e) {
        System.out.println("catch execute");
    
    } finally {
        System.out.println("finally execute");
    }
    
    输出
    try execute
    catch execute
    finally execute
    

    4.有catch(catch异常)

    try {
        System.out.println("try execute");
    
    } catch (Exception e) {
        System.out.println("catch execute");
        throw new RuntimeException("catch Exception");
    
    } finally {
        System.out.println("finally execute");
    }
    
    输出
    try execute
    finally execute
    

    5.有catch(try/catch都异常)(会抛出异常)

     try {
        System.out.println("try execute");
        throw new RuntimeException("try Exception");
    
    } catch (Exception e) {
        System.out.println("catch execute");
        throw new RuntimeException("catch Exception");
    
    } finally {
        System.out.println("finally execute");
    }
    
    输出
    try execute
    catch execute
    finally execute
    Exception in thread "main" RuntimeException: catch Exception
    
    

    6. 没有catch(无异常)

    try {
        System.out.println("try execute");
    } finally {
        System.out.println("finally execute");
    }
    
    输出
    try execute
    finally execute
    

    7. 没有catch(try异常)(会抛出异常)

    try {
        System.out.println("try execute");
        throw new RuntimeException("try Exception");
    
    } finally {
        System.out.println("finally execute");
    }
    
    输出
    try execute
    finally execute
    Exception in thread "main" ServiceException: try Exception
    

    8. 有返回值(try)(程序返回"try return")

    try {
        System.out.println("try execute");
        return "try return";
    
    } finally {
        System.out.println("finally execute");
    }
    
    输出
    try execute
    finally execute
    

    9. 有返回值(catch)(程序返回"catch return")

    try {
        System.out.println("try execute");
        throw new RuntimeException("try exception");
    
    } catch (Exception ex) {
        return "catch return";
    } finally {
        System.out.println("finally execute");
    }
    
    输出
    try execute
    finally execute
    
    

    三. finally不会执行的情况

    1. 调用 System.exit 函数

    try {
        System.out.println("try execute");
        System.exit(1);
    
    } catch (Exception ex) {
    
        System.out.println("catch execute");
    
    } finally {
    
        System.out.println("finally execute");
    }
    
    输出
    try execute
    
    

    2. 调用 halt 函数

    try {
        System.out.println("try execute");
        Runtime.getRuntime().halt(1);
    
    } catch (Exception ex) {
    
        System.out.println("catch execute");
    
    } finally {
    
        System.out.println("finally execute");
    }
    
    输出
    try execute
    
    

    四. 常见问题

    1. 忽略异常(程序返回"finally return")

    try {
        System.out.println("try execute");
        throw new RuntimeException("try exception");
    
    } finally {
    
        System.out.println("finally execute");
        return "finally return";
    }
    
    输出
    try execute
    finally execute
    
    

    2. finally存在return语句,则 try 和 catch 存在的返回语句就会被忽略(程序返回"finally return")

    try {
        System.out.println("try execute");
        return "try return";
    
    } finally {
        System.out.println("finally execute");
        return "finally return";
    }
    
    输出
    try execute
    finally execute
    
    

    3. finally抛异常(不会有返回值,一直抛出异常 RuntimeException)

    try {
        System.out.println("try execute");
        return "try return";
    
    } finally {
    
        System.out.println("finally execute");
        throw new RuntimeException("finally exception");
    }
    
    输出
    try execute
    finally execute
    Exception in thread "main" java.lang.RuntimeException: finally exception
    
    

    4. finally异常覆盖try异常

    try {
        System.out.println("try execute");
        throw new RuntimeException("try exception");
    
    } finally {
    
        System.out.println("finally execute");
        throw new RuntimeException("finally exception");
    }
    
    输出
    try execute
    finally execute
    Exception in thread "main" java.lang.RuntimeException: finally exception
    
    

    5. finally异常覆盖catch异常

    try {
        System.out.println("try execute");
        throw new RuntimeException("try exception");
    
    } catch (Exception ex) {
    
        System.out.println("catch execute");
        throw new RuntimeException("catch exception");
    
    } finally {
    
        System.out.println("finally execute");
        throw new RuntimeException("finally exception");
    }
    
    输出
    Exception in thread "main" java.lang.RuntimeException: finally exception
    try execute
    catch execute
    finally execute
    
    

    6. finally异常覆盖其它异常原因及解决

    原因:一个方法只能抛出一种异常,无法出现两种

    解决1:finally代码块自行捕获和处理异常

    try {
        System.out.println("try execute");
    
    } finally {
    
        System.out.println("finally execute");
    
        try {
    
            throw new RuntimeException("finally exception");
    
        } catch (Exception ex) {
    
            log.error(ex.getMessage());
        }
    }
    
    输出
    try execute
    finally execute
    错误日志:finally exception
    

    解决2:异常追加

    Exception e = null;
    
    try {
        System.out.println("try execute");
        throw new RuntimeException("try exception");
    
    } catch (Exception ex) {
        System.out.println("catch execute");
        e = ex;
    
    } finally {
        System.out.println("finally execute");
        try {
    
            throw new RuntimeException("finally exception");
    
        } catch (Exception ex) {
    
            if (e != null) {
                e.addSuppressed(ex);
            } else {
                e = ex;
            }
        }
    }
    
    throw e;
    
    输出
    try execute
    catch execute
    finally execute
    Exception in thread "main" java.lang.RuntimeException: try exception
        Suppressed: java.lang.RuntimeException: finally exception
    
  • 相关阅读:
    如何设置ASP.NET页面的运行超时时间
    日志文件清理工具V1.1
    【原创】日志文件清理工具V1.0
    【分享】国外后台界面HTML源码 [免费]
    【分享】仿东软OA协同办公服务管理源码
    年底发福利了——分享一下我的.NET软件开发资源
    由12306动态验证码想到的ASP.NET实现动态GIF验证码(附源码)
    【分享】元旦送礼,商业源码免费赠送!
    给大家分享一个jQuery TAB插件演示
    【分享】双12了,也没啥可送大家的,就送大家点商业源码吧!
  • 原文地址:https://www.cnblogs.com/gossip/p/15512610.html
Copyright © 2011-2022 走看看