一般情況下,Java的違例實施方案都顯得十分出色。不幸的是,它依然存在一個缺點。盡管違例指出程序裡存在一個危機,而且絕不應忽略,但一個違例仍有可能簡單地“丟失”。在采用finally從句的一種特殊配置下,便有可能發生這種情況:
//: LostMessage.java // How an exception can be lost class VeryImportantException extends Exception { public String toString() { return "A very important exception!"; } } class HoHumException extends Exception { public String toString() { return "A trivial exception"; } } public class LostMessage { void f() throws VeryImportantException { throw new VeryImportantException(); } void dispose() throws HoHumException { throw new HoHumException(); } public static void main(String[] args) throws Exception { LostMessage lm = new LostMessage(); try { lm.f(); } finally { lm.dispose(); } } } ///:~
輸出如下:
A trivial exception at LostMessage.dispose(LostMessage.java:21) at LostMessage.main(LostMessage.java:29)
可以看到,這裡不存在VeryImportantException(非常重要的違例)的跡象,它只是簡單地被finally從句中的HoHumException代替了。
這是一項相當嚴重的缺陷,因為它意味著一個違例可能完全丟失。而且就象前例演示的那樣,這種丟失顯得非常“自然”,很難被人查出蛛絲馬跡。而與此相反,C++裡如果第二個違例在第一個違例得到控制前產生,就會被當作一個嚴重的編程錯誤處理。或許Java以後的版本會糾正這個問題(上述結果是用Java 1.1生成的)。