try {} catch {}
ブロック トレースとスタック トレースがどのように機能するかについて知りたいと思います。
例外処理のアンチパターンに関するこのすばらしい記事を読んでいて、次の段落を見つけました。
catch (NoSuchMethodException e) { throw new MyServiceException("Blah: " + e.getMessage()); }
これは元の例外のスタック トレースを破棄し、常に間違っています。
その後、私は自分がどのように機能するのかよくわからないtry/catch
ことに気づきました。私の理解は次のとおりです。例を考えてみましょう:
void top() {
try {
f();
} catch (MyException ex) {
handleIt();
} finally {
cleanup();
}
}
void f() {
g();
}
void g() {
throw new MyException();
}
を呼び出すtop()
と、コール チェーン はコール スタックにtop -> f -> g
2 つのスタック フレームを残します (top
およびf
関数用)。で例外が発生すると、プログラムは例外を処理するブロックがg
見つかるまで実行スタックをバブルアップします。try/catch
その間、スタックフレームを解放し、スタックトレース情報を渡してcatch
スタックトレースを出力できる「魔法の」オブジェクトに添付します。
呼び出された関数が try/catch ブロックで「囲まれている」ことをどのように知るのでしょうか? この情報はスタック フレームにバインドされていますか? 同様に、エラー処理ブロック (一致するcatch
ブロックを選択するいくつかのスイッチ) へのポインターと、finally
ブロックへのポインター? 上記の例で破壊的なのはなぜですかe.getMessage()
(コメントを参照)。
注、私は try/catch と例外の使用方法を知っています。内部でどのように機能するか知りたいです。