Java陷阱之:finally块抛出异常或return导致异常丢失

2023-06-19 14:29:35 浏览数 (1)


现象


java中finally语句包含有抛出异常或者return语句,会把try块中出现的异常丢弃。

示例


环境

代码语言:javascript复制
java version "17.0.1" 2021-10-19 LTS
Java(TM) SE Runtime Environment (build 17.0.1 12-LTS-39)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.1 12-LTS-39, mixed mode, sharing)

finally块中抛出异常

代码语言:javascript复制
public class FinallyLostException {
    public static void main(String[] args) {
        test();
    }

    private static void test() {
        try {
            throw new RuntimeException("try exe");
        } finally {
            throw new RuntimeException("finally exe");
        }
    }
}

运行结果:

代码语言:javascript复制
Exception in thread "main" java.lang.RuntimeException: finally exe
  at com.example.springcloudtest.spring.postprocessor.FinallyLostException.test(FinallyLostException.java:15)
  at com.example.springcloudtest.spring.postprocessor.FinallyLostException.main(FinallyLostException.java:8)

finally块中的异常覆盖了try块里的异常。

  • finally块中包含return语句
代码语言:javascript复制
public class FinallyLostException {
    public static void main(String[] args) {
        test();
    }

    private static void test() {
        try {
            throw new RuntimeException("try exe");
        } finally {
            return;
        }
    }
}

运行无异常抛出。

其实,这个是java异常设计缺陷,没能像C 一样处理。业务中碰到过finally块中抛出异常,导致原本呈现在日志中的try中的异常堆栈丢失。

java编程思想一本书中也谈到了这个现象。

总结


finally块抛出异常或return导致异常丢失,我们一定在finally中不要包含return语句,并且finally块中的所有代码必须try catch Throwable 打印异常堆栈,而不要再抛出去。


0 人点赞