11

saveがスローさiれ、 のみに使用されるとしsaveます。次のコード フラグメントは同じですか? Sematics、パフォーマンス、およびその他の側面を考慮してください。

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一般的に、関数のすべてのステートメントをブロックに配置するか、スローするステートメントだけを配置する必要があるかを知りたいです。

4

4 に答える 4

12

セマンティクスに関しては、try-catch コンストラクトを配置するメソッドを決定した場合 (そして、その決定を正しく行ったことに満足している場合)、答えはかなり単純です。

  • try一連のステートメントをブロックに含める必要があります。これらのステートメントの 1 つが失敗した場合、残りのシーケンスは破棄されます。それ以上でもそれ以下でもありません。

上記のアドバイスに正しく従えば、目的のプログラム フローやローカル変数の最も効率的なスコープなどの問題は、(ほとんどの場合) 非常に簡単かつ明確に解決されます。tryこれは、ネストされたブロックの可能性を排除していないことに気付くでしょう。

パフォーマンスに関しては、例外処理のオーバーヘッドは、スロー可能なオブジェクトを実際にスローしてキャッチすることにあります。つまり、実際にオーバーヘッドが発生するのは、例外が実際に発生した場合のみです。コード内に try-catch コンストラクトが存在するだけでは、測定可能なオーバーヘッドは発生しません (まったく発生しない可能性があります)。また、(特定の try-catch コンストラクト内の) ステートメントの量は、そのパフォーマンスとはまったく関係ありません。

編集:リンクするJVM仕様の詳細を見つけることができませでしたが、生成されたバイトコードを調べて説明するユーザーによる多くの投稿があります.興味深い結果)。私には、Java コンパイラーが出力をできるだけ少なくしようとしているように見えます (もちろん、tryおよびcatch句と、これらの句をジャンプしたり例外オブジェクトをポップしたりするためのいくつかの避けられないプログラム フロー命令)。例外がキャッチされる候補となる場所を見つける責任は VM に委ねられます。これにより、例外が実際に発生するシナリオにより多くの負担がかかる可能性が高くなりますが、ご存知のように、例外は例外的なケースのためのものであり、とにかくフローを制御するものではありません。

C++ 例外が一般的にどのように実装されているかはわかりませんが、C++ プログラムは通常 VM の助けを借りて実行されないことを考えると、例外が Java と根本的に異なることは非常に合理的です。

于 2013-06-20T19:24:09.450 に答える
5

それらは同じではありません。違いは変数のスコープですi。2 番目のケースでは、ブロックiの外では使用できません。try-catch

一般的に私が知りたいのは、関数のすべてのステートメントを try-catch ブロックまたはスローするブロックに配置する必要があることです。

try-catchより良い方法は、ブロック内で例外をスローする脆弱なコードをラップすることです。このようにして、特定のコード ブロックに関連する特定の例外を処理できます。したがって、1番目の方法が最適です。

于 2013-06-20T19:21:02.003 に答える
2

この場合:

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

Exception はあらゆる種類の (エラーを除く) のスーパー クラスであるため、すべての例外 (エラーを除く) がキャッチされますException。したがって、チェックされた例外だけでなく、チェックされていない例外も処理RuntimeExceptionされます。これがあなたの目標である場合は、この方法に従うことをお勧めします。一方、try...catchブロックのスコープを最小化することは良い習慣だと思います。なぜなら、例外が発生した場合に問題のあるコード行を見つける方が簡単だからです。

于 2013-06-20T19:26:30.433 に答える
1

Rohit は、ここで variable のスコープが異なることを (正しく) 指摘していiます。

追加の違いはcalculate()、Unchecked Exception をスローする場合です。ブロックに引っかかりcatchます。への呼び出しをブロックcalculate()内に配置する必要があるかどうかは、ここでブロック内tryから Unchecked Exception を処理するか、外側にスローできるようにするかによって異なります。私の意見では、それはチェックされていないため、完全に予想外であるため、呼び出しをブロックに入れません。calculate()catchcalculate()try

パフォーマンスに関しては、パフォーマンス ヒットはtryブロックに遭遇したときであり、両方のシナリオでブロックが 1 つしかないため、違いはないはずであるというのが私の意見です。次のように各行の周りに個別の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)
    }
}
于 2013-06-20T19:25:49.960 に答える