现象
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语句
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 打印异常堆栈,而不要再抛出去。