在实际的编码过程中,我们有时希望一部分 try 块中的代码无论是否抛出异常,它们都能得到执行,如释放打开的文件、关闭网络链接等。
在 try-catch 后面加上 finally ,可以实现这个效果,无论异常是否被抛出,finally 块中的语句都会执行。
public class FinallyWorks {
public static void f() throws Exception {
throw new Exception("throw exception");
}
public static void main(String[] args) {
try {
f();
System.out.println("no exception");
} catch (Exception e) {
System.out.println("caught exception");
} finally {
System.out.println("In finally clause");
}
}
}
caught exception
In finally clause
假设在 finally 之前进行了 return 操作, finally 中的代码还能执行嘛?
public class MultipleReturns {
public static void f(int i) {
System.out.println("Initialization that requires cleanup");
try {
System.out.println("Point 1");
if (i == 1) return;
System.out.println("Point 2");
if (i == 2) return;
System.out.println("Point 3");
if (i == 3) return;
} finally {
System.out.println("Performing cleanup");
}
}
public static void main(String[] args) {
for (int i = 0; i < 4; i++) {
f(i);
}
}
}
Initialization that requires cleanup
Point 1
Point 2
Point 3
Performing cleanup
Initialization that requires cleanup
Point 1
Performing cleanup
Initialization that requires cleanup
Point 1
Point 2
Performing cleanup
Initialization that requires cleanup
Point 1
Point 2
Point 3
Performing cleanup
Process finished with exit code 0
由上述例子可见,无论在哪个点执行 return ,finally 中的代码都得到了执行。
但遗憾的时,如果 finally 使用不恰当,会造成异常丢失。比如下面这个例子:
public class VeryImportantException extends Exception {
@Override
public String toString() {
return "A very important exception!";
}
}
public class HoHumException extends Exception {
@Override
public String toString() {
return "A trivial exception";
}
}
public class LostMessage {
public void f() throws VeryImportantException {
throw new VeryImportantException();
}
public void dispose() throws HoHumException {
throw new HoHumException();
}
public static void main(String[] args) {
LostMessage lostMessage = new LostMessage();
try {
try {
lostMessage.f();
} finally {
lostMessage.dispose();
}
} catch (Exception e) {
System.out.println(e);
}
}
}
A trivial exception
VeryImportantException 被 finally 中的 HoHumException 所取代,应当尽力避免这种使用方式。
除此之外,还有一种各位简单的异常丢失方式:
public class ExceptionSilencer {
public static void main(String[] args) {
try {
throw new RuntimeException();
} finally {
return;
}
}
}
在 finally 中使用 return 会造成异常的丢失。
本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。
若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!