Java: throw 的屏蔽作用
在其所在的块内 (如方法 body、if () {...}
等),throw
语句可以屏蔽其后的语句,即在块内,该 throw
语句后面不能再写其他语句;但在块之外,还是可以写其他的语句的。如:
public class ExceptionTest {
private static void func() throws Exception {
throw new Exception();
//System.out.println("Threw Exception"); // error
}
private static void func2() throws Exception {
boolean tag = true;
if (tag) {
throw new Exception();
//System.out.println("Threw Exception"); // error
}
System.out.println("No Exception"); // pass // Mark No.3
}
public static void main(String[] args) {
try {
func2(); // Mark No.1
throw new Exception(); // Mark No.2: direct throw in try
} catch (Exception e) {
System.out.println("Caught Exception");
}
System.out.println("Continue"); // Mark No.4
}
}
//output:
/*
Caught Exception
Continue
*/
如果不是直接在 try
中抛出异常 (Mark No.2
),而是调用会抛出异常的方法 (Mark No.1
),一旦 throw
语句执行,则包含该 throw
语句的方法 (如本例的 func2()
) 直接退出,后续的语句都不执行 (如 Mark No.3
处就没有运行)。而处理异常的函数 (如本例的 main()
) 依旧是顺序运行,不会有什么影响,后续的语句继续运行 (如 Mark No.4
处照常运行)。
2011-10-27补充:多个 throw
的覆盖作用
如果你 throw 了一个 Exception,紧接着后面的 catch
/finally
也 throw 了一个 Exception,那么,只有最后抛出的 Exception 才能被外围捕捉,前面 throw 的 Exception 就被覆盖掉了。
一个典型的可能的例子是:
try {
// 读文件
} finally {
if (io != null) {
io.close();
}
}
如果读文件时出了 FileNotFoundException
,而不巧 io.close()
也出了 IOException
,那么外围只能捕捉到 IOException
,而真实的原因 FileNotFoundException
却捕捉不到。
Practical Java 上一个略奇葩的思路是用一个 Collection
来保存 Exception
,最后 throw 出一个 AllException(Collection<Exception> c)
这样的异常出来。
Comments