13

Java では、後に 1 つのステートメントのみを実行する必要がある場合、ifまたはfor括弧は必要ありません。私たちは書くことができます:

if(condition)
  executeSingleStatement();

また

for(init;condition;incr)
  executeSingleStatement();

しかし、catch ブロックの場合、なぜブラケットを省略できないのでしょうか? なぜこれが不可能なのですか?

catch(Exception e)
   e.printStackTrace();

なぜなら、ほとんどの場合私たちe.printStackTrace()テスト中またはログ中のステートメントのいずれかであるキャッチブロックにステートメントが1つしかありません。

4

7 に答える 7

7

コンパイラ構築の教科書を見つけて、dangling-else ambiguityを調べてください。

Java やその他の恐ろしい構文を持つほとんどの言語では、スペースが存在します。どのように解釈しますか:

try
try
stuff();
catch (FooException exc)
handle(exc);
catch (BarException exc)
handle(exc);
catch (BazException exc)
handle(exc);

それは...ですか:

try {
    try {
        stuff();
    } catch (FooException exc) {
        handle(exc);
    } catch (BarException exc) {
        handle(exc);
    }
} catch (BazException exc) {
    handle(exc);
}

または:

try {
    try {
        stuff();
    } catch (FooException exc) {
        handle(exc);
    }
} catch (BarException exc) {
    handle(exc);
} catch (BazException exc) {
    handle(exc);
}

dangling-else のあいまいさは、elseを最も内側の に関連付けることによって解決されifます。この貧弱なスタイルを処理するために、より複雑な複雑さを追加しますか? いいえ。

編集:例がカバーしていないコメントがありますcatch。/ではなく中括弧を必要とするのは、適切な 奇妙な決定です。とにかく、完全を期すために、次のコードを検討してください。trycatchfinally

try {
stuff();
} catch (FooException foo)
try {
handle(foo);
} catch (BarException bar)
handle(bar);
catch (BazException baz)
handle(baz);
finally
release();

catchBazExceptionとはfinally、インナーまたはアウターに関連付けられていtryますか? ここでも、言語設計委員会は曖昧さをなくすために大量の文法を追加できたかもしれませんが、ここでも明示的なスタイルが優先されます。Sun/Oracle での私の仕事は、言語が簡素化されて明示的な中括弧がすべての場所に義務付けられていれば、もう少し楽だったでしょう。

于 2011-06-22T11:57:24.290 に答える
5

Java がそれを許可しない理由はわかりませんが、一般的に言えば、ステートメントが 1 つしかない場合でも、ブラケットを使用する方が良いスタイルです。読みやすく、展開しやすくなります。

角かっこを使用するかどうかに対処する関連する質問を次に示します。

于 2011-06-22T05:23:43.287 に答える
5

可能か不可能かの問題ではありません。それは単なる言語 (構文) 設計上の決定です。

Java 言語パーサーにはいくつかの実装があります。1 日もかからずにパーサー ソースを変更し、括弧で囲まれていない catch ステートメントを許可することができます。

http://www.google.com/search?q=java+パーサー

Java 言語の文法にも注意してください。

于 2011-06-22T11:42:11.723 に答える
2

From the Java Language Spec 3.0 - 第 14 章を見ると、ブロックとステートメントについて説明されています。ブロックは { と } で識別され、多くのステートメントが含まれています。Try/catch/finally はブロックであり、言語仕様に従って { } でグループ化する必要があります。

于 2011-06-22T05:39:20.977 に答える
1

また、役に立たないコードを書いても何のメリットもないと思いますし、テキストが多いほど簡単になることもわかりません。

私は一行キャッチを正確に一行で書くことで自分自身を助けます:

catch (InvalidArgumentException e) { die (e.getMessage()); }
catch (Exception e)                { die (e); }

私にとっては、これが最も読みやすい方法です。人々が完全な小説を例外名に書き込もうとすると、混乱するだけです。

catch (CanNotPayAttentionToThatManBehindTheCurtainThrowableRuntimeExceptionWithMessageAndCouseContainItselfAnotherCourseAndMessage e) ...
于 2013-03-12T16:39:22.780 に答える
0

おそらくC++から継承されています。C++がそれを行った理由はわかりません。ここで私の考えを参照してください:https ://stackoverflow.com/questions/6254595/how-do-you-use-the-return/6255489#6255489

{}また、文法が単純になる、つまり言語デザイナーの生活が楽になることも注目に値します。このif声明は良い例です-あなたが好きな便利さは安くはありません。

のような曖昧さのために

if(c1) if(c2) A; else B;

interpretation 1 
if(c1)
    if(c2) 
        A;
    else 
        B;

interpretation 2 
if(c1)
    if(c2) 
        A;
else 
    B;

ifあいまいさを解決するには、の文法を微調整する必要があります。任意のblock代わりにが必要であるとすると、。statementが存在するため、文法ははるかに単純になり{}ます。

だから彼らはたぶん怠惰な気分だった。

于 2011-06-22T05:59:30.040 に答える
0

「ほとんどの場合」、スタック トレースを印刷またはログに記録するだけでなく、それ以上のことを行う必要があると私は主張します。これは、例外を飲み込んでいることを意味しますが、これは一般的には良い習慣ではありません。少なくとも、例外から正常に回復できない場合は、ログに記録して、スタックの上位のコードで可能になる場合に備えて再スローする必要があります。

とはいえ、「それが彼らが設計した方法です」を超えて、あなたの質問に対する答えは本当にないと思います。

于 2011-06-22T05:29:13.390 に答える