3 回答

TA貢獻1809條經驗 獲得超8個贊
建筑
try { ... }
catch () { ... } /* You can even omit the () here */
try { ... }
catch (Exception e) { ... }
兩者相似,因為兩者都將捕獲塊中拋出的每個異常try(并且,除非您只是使用它來記錄異常,否則應避免)。現在來看這些:
try { ... }
catch ()
{
/* ... */
throw;
}
try { ... }
catch (Exception e)
{
/* ... */
throw;
}
try { ... }
catch (Exception e)
{
/* ... */
throw e;
}
第一個try-catch塊和第二個try-catch塊完全相同,它們只是重新拋出當前異常,并且該異常將保留其“源”和堆棧跟蹤。
第三個try-catch塊是不同的。當它引發異常時,它將更改源和堆棧跟蹤,以便看起來已從此方法引發異常,從throw e包含try-catch塊的方法的那一行開始。
您應該使用哪一個?這實際上取決于每種情況。
假設您有一個Person帶有.Save()將其持久化到數據庫中的方法的類。假設您的應用程序在Person.Save()某處執行該方法。如果您的數據庫拒絕保存Person,.Save()則將引發異常。您應該使用throw還是throw e在這種情況下?這要看情況。
我更喜歡做的是:
try {
/* ... */
person.Save();
}
catch(DBException e) {
throw new InvalidPersonException(
"The person has an invalid state and could not be saved!",
e);
}
這應該將DBException作為正在拋出的較新異常的“內部異?!?。因此,當您檢查此InvalidPersonException時,堆棧跟蹤將包含返回Save方法的信息(這可能足以解決問題),但是如果需要,您仍然可以訪問原始異常。
最后一點,當您期望一個異常時,您應該確實捕獲該特定的異常,而不是一般的異常Exception,即,如果您期望一個InvalidPersonException,則您應該首選:
try { ... }
catch (InvalidPersonException e) { ... }
至
try { ... }
catch (Exception e) { ... }
祝好運!

TA貢獻1820條經驗 獲得超3個贊
第一個保留堆棧跟蹤,而第二個重置堆棧跟蹤。這意味著,如果您使用第二種方法,則異常的堆棧跟蹤將始終從該方法開始,并且您將丟失原始的異常跟蹤,這對于讀取異常日志的人可能是災難性的,因為他將永遠找不到異常的原始原因。 。
當您想向堆棧跟蹤中添加其他信息時,第二種方法可能會很有用,但它的用法如下:
try
{
// do something
}
catch (Exception ex)
{
throw new Exception("Additional information...", ex);
}

TA貢獻2080條經驗 獲得超4個贊
無參數catch和a之間的區別catch(Exception e)是您可以引用該異常。從框架版本2開始,非托管異常包裝在托管異常中,因此無參數異常不再對任何事物都有用。
throw;和之間的區別throw e;是,第一個用于引發異常,第二個用于引發新創建的異常。如果使用第二個異常拋出異常,它將把它當作新異常對待,并替換最初拋出異常時的所有堆棧信息。
因此,您不要在問題中使用任何一種替代方法。您不應使用無參數捕獲,而應使用它throw;來拋出異常。
同樣,在大多數情況下,對于所有異常,應使用比基類更具體的異常類。您應該只捕獲預期的異常。
try {
...
} catch (IOException e) {
...
throw;
}
如果要在引發異常時添加任何信息,請創建一個新異常,并將原始異常作為內部異常保留所有信息:
try {
...
} catch (IOException e) {
...
throw new ApplicationException("Some informative error message", e);
}
- 3 回答
- 0 關注
- 931 瀏覽
添加回答
舉報