簡體   English   中英

有一個try-catch塊,你應該在其中放置所有語句還是只放置不安全的語句?

[英]Having a try-catch block, should you place ALL statements in it or just the unsafe one?

假設save投擲, i僅用於save 以下代碼片段是否相同? 請考慮語義, 性能和其他方面。

void bob(){
  int i = calculate();
  try {
    save(i);
  } catch(Exception e){
    report(e)
  }
}

void bob(){
  try {
    int i = calculate();
    save(i);
  } catch(Exception e){
    report(e)
  }
}

一般來說,我想知道,如果一個函數的所有語句都放在try-catch塊中,或者只是拋出一個函數。

語義方面,如果你已經決定將你的try-catch構造放入哪種方法(並且你對你做出正確的決定感到滿意),那么答案很簡單:

  • 您應該在try塊中包含一系列語句,如果其中一個語句失敗,則應該放棄序列的其余部分 沒有更多,也沒有更少的陳述。

如果您正確地遵循上述建議,那么很容易且很明顯地(在大多數情況下)解決諸如所需程序流和最有效的局部變量范圍之類的問題。 您會注意到這並不排除嵌套try塊的可能性。

性能方面,異常處理的開銷在於實際拋出和捕獲可拋出對象。 換句話說, 只有在實際發生異常時才真正有開銷。 代碼中僅存在try-catch構造不會引入任何可測量的開銷(可能根本沒有)。 此外,語句的數量(在給定的try-catch構造內)與其性能完全無關。

編輯:我找不到要鏈接到的JVM規范中的任何細節,但有很多用戶檢查和解釋生成的字節碼的帖子, 比如這個這個 (在許多其他人中 - 谷歌搜索會產生一些有趣的結果)。 對我來說,看起來Java編譯器嘗試盡可能少地發出(當然,除了你在trycatch子句中放入的實際代碼以及一些不可避免的程序流指令跳轉到所述子句或彈出異常對象,如果有的話)。 它留給VM負責找出異常被捕獲的位置。 這很可能會將更多的負擔轉移到實際發生異常的場景中,但是,正如我們所知,異常是針對特殊情況,而不是控制流。

我承認我不知道C ++異常通常是如何實現的,但考慮到C ++程序通常不在VM的幫助下運行,它們與Java完全不同是非常合理的。

他們不一樣。 不同之處在於變量i的范圍。 在第二種情況下,您不能在try-catch塊之外使用i

一般來說,我想知道,如果一個函數的所有語句都放在try-catch塊中,或者只是拋出一個函數。

更好的方法是將代碼容易包裝在try-catch塊中拋出異常。 這樣,您就可以處理與特定代碼塊相關的特定異常。 所以,第一種方式是要去的方式。

在這種情況下:

void bob(){
  try {
    int i = calculate();
    save(i);
  } catch(Exception e){
    report(e)
  }
}

所有的異常(錯誤除外)會被抓住,因為異常是一個超類所有種類的Exception (錯誤除外)。 因此,不僅會處理已檢查的異常,還會像RuntimeException一樣取消選中。 如果這是你的目標,那么我建議采用這種方式。 另一方面,我認為最小化try...catch塊的范圍是一個很好的做法,因為如果找到有問題的代碼行的異常更容易。

Rohit指出(正確地)變量i的范圍在這里是一個區別。

另外一個區別是如果calculate()拋出一個未經檢查的異常; 它將被catchcatch 是否應該在try塊中調用calculate()取決於您是否要在此處的catch塊中處理calculate()中的Unchecked Exception,或者允許它向外拋出。 在我看來,由於它是未經檢查的,因此完全出乎意料,我不會在try塊中調用calculate()

關於性能 ,我認為應該沒有區別,因為性能命中是遇到try塊而你在這兩種情況下只有一個塊。 如果你在每行周圍有單獨的try-catch塊,那么性能可能會降低,但可能沒有你曾經注意到的任何方式:

// degraded performance example
void bob(){

    int i;

    try {
        i = calculate();
    } catch(Exception e){
        report(e)
    }

    try {
        save(i);
    } catch(Exception e){
        report(e)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM