7

インタビューで、tryブロックとcatchブロックの間にfinallyブロックを配置するとどうなるかという質問がありました。その場合、コンパイラはcatchブロックがないと見なし、finallyブロックを直接実行します。次に、tryブロックとcatchブロックの間にコードを配置できないのはなぜですか?

手伝ってくれませんか...

4

5 に答える 5

11

まず最初に、コンパイラはコードを実行するのではなく、コンパイルするだけで、JVM で実行できるようにします。

経験的に言えば、それはあまり意味がありません。なぜなら、try ブロックの外側で catch ブロックの前に配置したいコードがある場合、コードを try ブロックに配置することもできるからです。問題は、考えてみれば、とにかく try ブロックにあったように動作するということです。

これが有効な Java であると仮定しましょう(これはコンパイルされません):

try {
    throw new Exception();
}
System.out.println("Sup!");
catch(Exception e) { }

例外がスローされると、JVM が処理する適切な例外ハンドラーにジャンプするために検索しているため、出力されるその行はSup!スキップされますException。したがって、ある意味では、コードは try {} ブロック自体にある場合と同じように動作します。そのため、コードがどこにあるかは問題ではなく、Java では、この (現在は役に立たないことが証明されている) 構造は次のように指定されています。違法。

try の後のコードが別の例外自体をスローした場合はどうなるでしょうか。有効なコードであれば、元の try ブロックに入れ子になった try...catch ブロックのように動作します。もちろん、物事が複雑になり始めると、try ブロックと catch ブロックの間に明確な接続がないアプローチはあいまいになる可能性があり、JVM はどの catch/finally がどの try ブロックに属しているかを認識できなくなる可能性があります (特にハンドラーが同じ関数にある必要はなく、同じパッケージにある必要さえありません!)。

于 2012-07-11T06:46:42.943 に答える
5

まあ、軽率な答えは、言語仕様で禁止されているということです。

しかし、少し戻って別の方法で考えてみましょう。これができるとしたらどうでしょか。

try {
  foo();
}
bar();
catch (Exception e) {
  baz();
}

これのセマンティクスは何でしょうか? で例外をキャッチするとfoo()、 がbaz()呼び出されますか? どうbar()ですか?スローされた場合bar()、その場合に例外をキャッチしますか?

の例外bar()がキャッチされfoo()、例外が実行されないbar()場合、構文は次と同等です。

try {
  foo();
} catch (Exception e) {
  baz();
}
bar();

の例外bar() キャッチされ、例外の実行がfoo()妨げられるbar()場合、構文は次と同等です。

try {
  foo();
  bar();
} catch (Exception e) {
  baz();
}

の例外bar()がキャッチされ、例外の実行が妨げられfoo() ないbar()(bar()が常に実行される) 場合、構文は次と同等です。

try {
  foo();
} catch (Exception e) {
  baz();
} finally {
  bar();
}

おわかりのように、この between-try-catch 構造の妥当なセマンティクスは、新しい (そしてややこしい) 構造を必要とせずにすでに表現可能です。まだ冗長でないこの構造の意味を考案するのは困難です。

余談ですが、これができない理由として考えられるのは次の 1 つです。

try {
  foo();
} finally {
  bar();
} catch (Exception e) {
  baz();
}

実際の実行順序を反映していない可能性があります - catch ブロックは finally ブロックの前に実行されます。これにより、catch ブロックは、finally ブロックが後で解放する可能性のあるリソースを利用できます (たとえば、RPC オブジェクトなどから追加の診断情報を要求するため)。他の方法でも機能するようにすることはできますか?もちろん。その価値はありますか?おそらくそうではありません。

于 2012-07-11T08:13:24.873 に答える
4

それは次のような意味になります。

try
{
   somCode();
}
someMoreCode();
catch
{
}

これはどういう意味ですか? セマンティックがないため、これは不可能です。したがって、言語設計者によって構文的に正しくないと判断されました。

于 2012-07-11T06:43:42.883 に答える
0

Java 言語仕様 14.20 "The try ステートメント` で定義されているように、またはのtryいずれかが必要です。catchfinally

于 2012-07-11T06:44:14.103 に答える
0

.. if と else .. のように try と catch を行うため、try と catch ブロックの間にコードを追加する必要はありません

于 2012-07-11T06:45:48.703 に答える