Java – if文をブロック化すべき理由とelse if

概要

  • Javaにはif-then構文と、if-then-else構文の2つがある
  • それぞれのtrue/falseに応じた実行文は、1つの文やブロックなどでなければならない
  • else ifという構文はなく、else句の実行文にif-thenやif-then-else文を連ねたもの
  • if-then文やif-then-elseには原則として{}ブロックを使うべき

Java仕様におけるif/if-else/else ifの扱い

Oracleの仕様書では、if文の種類としてif-then文とif-then-else文が定義されている。しかし、”else if”という定義はされていない。

if-then文

if-then文の書式は以下のように定義されている。

IfThenStatement: if (Expression) Statement

Oracleの仕様によれば、Statementとして書けるのは以下の6つとされている。

  • StatementWithoutTrailingSubstatement
  • LabeledStatement
  • IfThenStatement
  • IfThenElseStatement
  • WhileStatement
  • ForStatement

いずれも単一の文であり、複数の文を書くことはできない。

if-then-else文

一方、if-then-else文は以下のように定義されている。

IfThenElseStatement: if (Expression) StatementNoShortIf else Statement

そしてStatementNoShortIfとして書けるのは次のいずれかとされている。

  • StatementWithoutTrailingSubstatement
  • LabeledStatementNoShortIf
  • IfThenElseStatementNoShortIf
  • WhileStatementNoShortIf
  • ForStatementNoShortIf

こちらも複数の文を書くことはできない。

ブロックは書ける

上記のように、if-then文やif-then-else文には、独立した複数の文を書くことはできない。

ただし双方で記述可能なIfThenStatementを見ると、Blockが記述可能となっている。

  • Block
  • EmptyStatement
  • ExpressionStatement
  • ・・・・・

したがって{}ブロックを使えば、他言語のif…else…endif構文のように複数の文を並べることができる(逆にそうしなければ書けない)。

else if

ブロックで書く

ところで、Javaの仕様ではelseifに相当するキーワードも構文も定義されていない。ただし、else句の後にif-then文やif-then-else文を書いて、同様のロジックとすることはできる。ただし、このときに原則として{}ブロックで書くべきである。

ブロック化すべき理由

先の仕様で、if-then文のStatementにはifTthenStatementifThenElseStatementがかけるが、if-then-else文のif-then句ではifThenElseStatementが書けないことになっている。これが何を意味するか試してみよう。

まずif-then文の実行文としてifThenStatementあるいはifThenElseStatementを連ねた場合。想定通り真偽条件に応じた結果が出力されている。

次にif-then-elseの第1ステートメントにifThenElseStatementを書いた場合。この場合も想定通りの結果になる。

ここで、仕様で想定されていない構成にしてみる。if-then-else文の第1ステートメントには、ifThenElseStatementが想定されているが、ifThenStatementは想定されていない。これを無視してifThenStatementを書いたのが以下。

これは インデントで表現すると以下のようなロジックを想定している。ところがその想定と異なる動作になってしまう。

このことはOracleの仕様書14.5. Statementsに書かれていて、”else句は(そのelseより前の)最も内側のifに属する”こととされている。つまり上の文を解釈通りのインデントにすると以下のようになる。

もしこの文を当初のロジックにしたければ、以下のようにブロック化しなければならない。

これで想定通り何も表示されず、想定ロジック・インデント通りの動作となる。

このようなelse句の解釈や、if-then文のStatementを追加する場合を考慮すると、たとえ1行の文でもブロック化すべきということになる。

余談

StatementNoShortIfとしてforやwhileの単文も書くことができる。

しかしながら、こういう表現も思わぬトラブル防止のためにブロック内に書いておいた方が安全だろう。

 

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です