2013-03-21 40 views
5

假設這段代碼是20米的地方,總是相同的捕捉單獨的異常或使用的instanceof - Java 6中

try { 
    // do something 
} catch (FirstException e) { 
    // log it 
} catch (SecondException e) { 
    // log it 
} 

豈不是更好地使用這樣的事情還是instanceof是不是好的解決辦法?

try { 
    // do something 
} catch(Exception e) { 
    logException(e); 
} 

void logException(Exception e) { 
    if (e instanceof FirstException) { 
     // log it 
    } else if (e instanceof SecondException) { 
     // log it differently 
    } else { 
     // do something with other exception 
    } 
} 

,我真的很討厭有關解決方案的唯一的事情就是抓住Exception這是definitelly不是最好的辦法...有什麼更好的辦法?

+0

我會使用第一種方法,併爲所有捕獲的異常調用logException。 – Thihara 2013-03-21 08:48:51

+0

如果發生'FileNotFoundException',會發生什麼情況! – Azodious 2013-03-21 08:50:47

+0

分別捕獲每個異常只有在您打算對每個異常執行不同的處理時纔有意義。在現實世界的應用中,這種情況很少。可行的方法是,如果運行時錯誤是一個主要問題並且**正確記錄它們,那麼使用超類「Exception」或「Throwable」來捕獲em'全部,以便對開發人員在何處以及實際發生的事情有意義。 – Vrushank 2013-03-21 09:08:52

回答

8
  1. 在Java 7中,使用catch (FirstException1 | SecondException | ...)
  2. 有可能是沒有錯catch (Exception e) —你想記錄所有例外,不是嗎?其實我會建議catch (Throwable t),因爲OutOfMemoryError s和StackOverflowError s也想被記錄。

多年來有關記錄異常的經驗告訴他們,他們都以同樣的方式記錄。作爲人類可讀的文本,異常消息是足夠的,開發人員真正需要調試的是棧跟蹤。

只是要小心一兩件事:永遠不要捕獲異常太早:趕上他們在整個應用程序一個地方,所謂例外屏障 —這是在您進入和退出的單位水平工作。

如果檢查的異常是給你在較低水平的麻煩,他們包裝成RuntimeException

try { 
    ... 
} 
catch (RuntimeException e) {throw e;} 
catch (Exception e) {throw new RuntimeException(e);} 

只有,如果你確切地知道並提前存在是具有商業級的意義異常你的應用程序,並且將而不是中止當前的工作單元,但重定向它的流程,是否適合在較低級別捕獲該異常。實際上,與應用程序代碼拋出的所有可能異常的總和相比,這些異常很少見。

+2

是不是像所有的最大的邪惡一樣可以投擲?因爲我不想捕捉所有的例外......只有兩個 – user219882 2013-03-21 08:53:15

+0

只有當你趕上他們太早---正如我在編輯答案中解釋的那樣。 – 2013-03-21 08:55:12

+0

謝謝 - 不知道你可以捕捉異常a | b在java 7中(最近主要在Obj-C中工作)。 。 。方便的提示。 – 2013-03-21 09:00:34

1

第一種方法肯定更好。通常這是一個不好的做法,趕上Exception,因爲在這種情況下,你也趕上RuntimeException

1

如果您只需記錄例外情況,那麼前者是乾淨而優秀的解決方案。

其他第一種方法更好。

1

在「重構模式」一書中,常見的重構之一是「用多態性替換instanceof」 - 換句話說,無論何時使用instanceof,都應考慮多態性是否會更好地工作。 。 。儘管如此,對於這個特定的問題,Spring的使用運行時異常替換檢查異常的理念會引起人們的注意(原諒雙關語)。

這個想法是,檢查的異常可以被過度使用 - 是可以從中恢復的異常嗎?如果是的話,好的。 。 。如果沒有,只要讓它傳播上去。你可以這樣做:

  • 重新投擲它。 。 。 (但更好)
  • 把它包在一個RuntimeException

創建日誌看點:

另一個要考慮的是,如果你確實需要的恰恰是他們所發生的點來記錄這些例外而不是讓他們傳播鏈條,他們發生在20個不同的地方,然後他們是一個交叉的關注點,而不是讓他們傳播鏈條,。 。 。您可以讓常規方法重新拋出異常,然後編寫一個方面來捕獲並記錄它們。 。 。 。再次使用Spring使得這很容易。