也許你會碰到如下代碼:
1.設計意圖不明顯,可讀性差
2.使用異常作為遍歷結束的條件,企圖訪問數組之外的元素,用拋出、捕獲、忽略數組越界異常的手段來達到終止循環的目的.
下面的標準模式,一目了然.
for (Mountaion m : range) {
m.climb();
}
為什么優先異常的模式,而不是用行之有效標準模式呢?
可能被誤導了,企圖利用異常機制提高性能,因為jvm每次訪問數組都需要判斷下標是否越界,他們認為循環終止被隱藏了,但是在foreach循環中仍然可見,這無疑是多余的,應該避免.
上面想法有三個錯誤:
1.異常機制設計的初衷是用來處理不正常的情況,所以JVM很少對它們進行優化.
2.代碼放在try..catch中反而阻止jvm本身要執行的某些特定優化
3.對數組進行遍歷的標準模式并不會導致冗余的檢查.
現在jvm實現,基于異常模式要比標準模式慢得多.
基于異常模式模糊了代碼意圖,降低它的性能,并且無法保證正常工作!如果出現bug,模式可能會悄悄失效,并且掩蓋這個bug,增加調試過程的復雜性.假設循環中調用某個方法執行不相關數組的越界異常訪問,使用合理模式,可以獲得完整的異常鏈,如果基于異常模式,這個bug會捕獲到,但是被誤解為正常循環終止條件. 案例的經驗是,異常只應該使用在異常情況下,它們永遠不應該用于正常的控制流中.
優先使用標準的,易于理解的模式,而不是那些聲稱可以提高性能,弄巧成拙的方法.即使可以提高性能,面對平臺不斷改進,這種基于異常的模式的優勢不可能一直存在,而維護的痛苦卻永遠存在.
總而言之,異常是為了在異常情況下使用而設計的。不要將它們用于普通的控制流,也不要編寫破事它們這么做的API。