2011-07-28 72 views
6

我想知道,是good practicecomplete code放在try block或我應該放置only the code which I feel it will cause a specific exception
我應該抓住基本的異常始終try/catch塊中的完整代碼

代碼1:在try塊完整的代碼

myFunction(){ 
try{ 
    ......... 
    Code with chance of OneException 
    ............. 
}catch(OneException e){ 
    ............ 
}catch(Exception e){ 
    .............. 
} 
} 

代碼2:只有代碼在try塊異常的機會

myFunction(){ 
    ....... 
    try{ 
    Code with chance of OneException 
    }catch(OneException e){ 
    ............ 
    } 
    ............ 
} 

代碼3:我應該總是發現異常

myFunction(){ 
     ....... 
     try{ 
     Code chance of OneException 
     }catch(OneException e){ 
     ............ 
     }catch(Exception e){ 
     .............. 
     } 
     ........ 
    } 

在此(code1,code2和code3)哪一個是最好的?
我主要關注Java和C++編碼

+1

C沒有例外,並且沒有稱爲C/C++的語言,因此您應該刪除'c'標記。 –

+1

最佳做法問題無法用於代碼審查 – 2011-07-28 21:49:01

+0

似乎更像是堆棧溢出問題,而不是代碼審查。我會投票遷移,但我沒有足夠的代表。 –

回答

5

一般來說,你應該只抓到你感興趣的異常,您可以處理。那就是......抓住一個例外,你可以做一些事情。用戶不會察覺到問題或何時明確需要告訴用戶該問題。
對於所有其他例外,讓他們彈出所有他們明顯記錄的細節(堆棧跟蹤等)。請注意,顯然這並不意味着用戶也應該看到該異常輸出,而不是一般性錯誤。

告訴我,當你寫「OneException異常的代碼」時,你知道如何處理OneException,但不是Exception,對嗎?那麼......只處理OneException。

3

總是抓住你的東西,沒有更多。無論我們嘗試多少,我們都無法使我們的代碼完全「白癡證明」。如果有人向你傳遞一些會導致一些隨機錯誤的事情,那麼處理它是他們的工作。如果我們的代碼處理其他人的異常,那麼這個異常就會產生意想不到的副作用。

至於什麼樣的代碼放在哪裏:代碼可能拋出異常的行會運行兩種方式之前,所以它並沒有真正會拋出代碼之前有意義有它try塊內和。在潛在異常之後的代碼應該放在try和catch之間,當且僅當它依賴於異常生成代碼。因此,如果您的數據庫連接調用可能失敗,請將所有數據庫查詢放入try塊中。

限制在try ... catch中花費的「時間」使得它更容易閱讀,並且更不易於意外捕捉。我不能告訴你有多少小時已經失去,因爲有人決定趕上應該傳播的異常。

+0

那麼我相信每個規則都有一個例外。假設我將一些代碼提供給其他人,並且在該代碼中我將收集一些統計數據。然後,我希望將該統計信息發送給我,並且我會將該整個代碼放入一個'try {} catch(Exception e){}因爲我不希望這會產生任何效果。即使我沒有收回任何東西也沒關係。我同意這將是一個晦澀的案例,但告訴我,如果這仍然是錯誤的。 – zidarsk8

1
  • a)在try塊中放置完整的代碼是一種不好的做法。

    • a1)除捕獲異常外,try-block是可能發生異常的文檔。所以把它放在靠近事業的地方,你要記住。
    • a2)在不好的情況下,你有一個閱讀文件,並且稍後添加一個用於寫入的文件,但是你的異常(FileNotFoundException)只是在寫出第一個時才寫的。圍繞有問題的地方的精益範圍將幫助您,找出進一步的問題。
  • b)不要捕獲完整性的基本例外或避免多個catch塊。如果你想寫一個文件,許多事情可能會出錯:缺少權限,非法文件名,設備上沒有剩餘空間......。如果您向用戶展示一個通用消息(「無法寫入文件」+名稱),他不知道該怎麼做。儘可能具體,你可以告訴他:「設備上只剩下20 MB」+ devicename +「我們需要另外8 MB(總共28 MB);請釋放一些空間並重復或選擇其他設備!」) 。如果你發現「異常」,機會很高,你正在考慮某種例外情況,但是又發生了另一種例外情況,而且處理不當,因爲沒有將這種可能性記在下面。 找到這個異常的最好機會是讓它彈出或記錄日誌是否定期控制。

它可以是開發應用程序,它被簡單地使用最終用戶之間,或者通過開發的API,它用於其他開發者的差。 在API中,您經常想要將異常封裝到自己的異常中,以便API的用戶更輕鬆地處理異常,以及是否有統一的方法來處理異常。如果你的代碼可以拋出許多異常,並會導致難看的客戶端代碼,您的客戶將需要一遍一遍地指定了一堆的例外,你經常換異常並重新拋出他們:

try { 
... 
} 
catch {FileNotFoundException fnfe} 
{ 
    throw new MyApiException (fnfe); 
} 
catch {PermissionDeniedException pde} 
{ 
    throw new MyApiException (pde); 
} 
catch {IOException ioe} 
{ 
    throw new MyApiException (ioe); 
} 

這樣,你的客戶可以決定,如何處理異常,並且如果感興趣的話,可以在異常中找到特定類型的異常。

由於Landei指出,在Java 7中會有一個簡化的技術,捕捉多個異常,但不是唯一的這樣一個共同的超類,看this link here

+0

Java 7中新的多重捕獲是有福的。請參閱http://www.baptiste-wicht.com/2010/05/better-exception-handling-in-java-7-multicatch-and-final-rethrow/ – Landei

+1

50%的Java人沒有采用簡化的for-loop,而你正在談論Java-7?也許你是一個早期採用的scala用戶,不是嗎? ;) –

+0

是的,我是一個早期適應癮君子... – Landei

1

裹的代碼點在哪裏,你真的可以處理例外情況以及可以處理錯誤的位置。如果你不能處理函數中的錯誤,那麼不要將代碼包裝在try/catch塊中。

我不知道對於Java,但在C++中,你應該通過const引用趕上:

try 
{ 
    // code that can throw an exception 
} 
catch (const SomeExceptionType & error) 
{ 
    // handle the error 
} 
1

C++是不是Java或C#或者......你需要catch(或finally)條款,自己清理。在C++中,RAII可以做到這一點。因此,我很少用C++編寫try/catch語句,以至於我認爲它是一種代碼異味。

因此,而不是考慮你應與try/catch使用的代碼風格,你應該問問自己是否需要該try/catch可言。

+0

+1代碼味道**。 –