【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
posted @ 2021-11-05 12:09    阅读(539)  评论(0编辑  收藏  举报