質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

5回答

964閲覧

Javaのif文の適切な書き方について

nvOSji1879

総合スコア2

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

1グッド

2クリップ

投稿2022/10/29 16:09

前提

Javaの学習中にふと思ったのですが、
if文について例となるサイトはいくつもありますが、例となっているものは、
if-else文か、if-else if - else文が多く、if-else ifの例があまり出てきません。
if-else if文は、一般的に使用しないのでしょうか。
下記の例で、args[0]に必ず"1"か"2"が代入されるケースだと、書き方①(if-else if)と②(if-else(コメントで補記))のどちらが望ましいでしょうか。
当たり前すぎる質問かもしれませんが、お答えいただけると幸いです。

該当のソースコード

Java

1public class Main { 2 3 private static final String OPTION1 = "1"; 4 private static final String OPTION2 = "2"; 5 6 public static void main(String[] args) { 7 String answer = args[0]; 8 9 // 書き方① 10 if (OPTION1.equals(answer)) { 11 System.out.println("〇"); 12 } else if (OPTION2.equals(answer)) { 13 System.out.println("×"); 14 } 15 16 // 書き方② 17 if (OPTION1.equals(answer)) { 18 System.out.println("〇"); 19 // answerが2の場合 20 } else { 21 System.out.println("×"); 22 } 23 } 24}
TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

要件次第です。
「外部からの任意の入力は信用しない」というのが原則です。
故に、バリデーション(入力値検査)を行って、意図しない外部入力を受け入れないように配慮します。

「1以外は全部2(×)とする」という仕様なのであれば、書き方②のほうで良いでしょう。

そうでないなら書き方①にelseを入れるか、それより前に「1でも2でもない場合は無効」という判定を入れて戻し(これがバリデーション)、アプリケーションを終了させるか再入力を促します。
(書き方①だけだと不十分になる可能性は高い)

投稿2022/10/29 19:46

編集2022/10/29 19:47
m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nvOSji1879

2022/10/30 03:26

ご回答ありがとうございました。 「「外部からの任意の入力は信用しない」というのが原則です。」というのを念頭に置いて、要件(仕様)に応じて判断したいと思います。 アプリケーションを終了させるか再入力を促すかは、要件によって判断したいと思いますが、「(書き方①だけだと不十分になる可能性は高い)」とのことなので、基本的には、if-else if ではなく、 if-elseかif-else if -elseを使用することを考えたいと思います。
m.ts10806

2022/10/30 04:01

直接的に答えると「ベストはない」です。 常に同じような実装が望ましいわけではありません。
guest

0

ベストアンサー

else ifを使えばその他の場合をさらに細分化できますが、重要なのは、細分化ではなく全ての場合を尽くすことです。この例で、ansewerの取りうる値の集合は何でしょうか。

answer = {1,2}
answer = {1,2,...}

最初の例だと全てを尽くす条件は以下のようになります

  • 1か、それ以外
  • 1か、2

2番目の例は、1,2以外の要素がある(後で追加されるかも知れない)ので、全てを尽くす条件は以下のようになります

  • 1か、それ以外
  • 1か、2か、それ以外

全ての場合を尽くさないと、漏れた値に対応できません。また、分割する集合に共通部分があると、バグやデッドコードを生じることがあります。

条件分岐はさまざまな書き方ができますが、 プログラミング言語に関係なく、次のように記述してください。

  • 全ての場合を尽くしていること
  • 条件分岐で分割する集合は互いに素(共通部分がない)こと

switchを使ってみます。default:を付けて全てを尽くしてください。

Java

1 // 書き方③ 2 if (answer == null) { 3 // nullを除外 4 throw new NullPointerException(); 5 } 6 switch (answer) { 7 case OPTION1: 8 // ... 9 break; 10 case OPTION2: 11 // ... 12 break; 13 default: 14 assert false; 15 }

投稿2022/10/30 00:17

編集2022/11/01 20:41
xebme

総合スコア1081

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xebme

2022/10/30 00:20 編集

ifを文ではなく式とみなす言語ではelseの省略を許しません。
xebme

2022/10/30 00:57

解答の主旨から少し外れますが、answerがnullの場合を問われるなら、elseは必須としておきましょう。nullは、不明というコードに置き換えてみると概念的にすっきりします
xebme

2022/10/30 02:10

assert false;を追加しました。コードは常に変更されるため。
nvOSji1879

2022/10/30 03:18

nullのケースが問われる場合では、else文に記載する(それ以外の値の条件とnull(不明)の条件をまとめて書く)ものばかりと思い込んでいましたが、書き方③のように、事前に明示的にnullチェックを書く書き方もあるとわかりました。 また、「2番目の例は、1,2以外の要素がある(後で追加されるかも知れない)ので、全てを尽くす条件は以下のようになります」の(後で追加されるかも知れない)の部分に関しては、考えてもおりませんでした。「assert false;を追加しました。コードは常に変更されるため。」も同様に、コードが変更(追加)されるときのことも考えて、修正しました。 if (answer == null) { // nullを除外 System.out.println("null"); } if (OPTION1.equals(answer)) { System.out.println("〇"); } else if (OPTION2.equals(answer)) { System.out.println("×"); } else { assert false : "想定外"; } assert false;に関しても、調べると「一応チェックしているけど、理論上有り得ないと思ってる」のような意思表示にもつかえるみたいなので、else文には、assert false;かthrow new UnsupportedOperationException();などのエラーをスローする処理を書こうと思います。 勉強になりました。ありがとうございました。 https://qiita.com/yskszk/items/ca98ec551886245182e3
jimbe

2022/10/30 04:43

>if (answer == null) { >// nullを除外 >System.out.println("null"); >} これだけでは除外していません。 結局 assert まで行きますので、 xebme さん回答の「条件分岐で分割する集合は互いに素(共通部分がない)こと」に抵触すると思います。 "null" 表示後は速やかにロジックを終わるべきでは無いでしょうか。
xebme

2022/11/01 20:45 編集

jimbeさんコメントを見落としていました。 nullの場合は例外を投げて早く失敗させます。nullはifの対象に含まないことになり、処理としては事前条件チェックに該当します。回答も修正しました。
guest

0

"必ず" をどこまで保証出来るかです。
else を書くだけの手間を省いた所為で "必ず" が守られなかった場合に問題が発生したら、コードを書いた本人は "仕様通りです" と言っても顧客の信用は無くすでしょう。
仕様通りだけでは無く、仕様通りで無い状態になる可能性も含めてコードを書いておいたほうが保険にはなります。

投稿2022/10/29 16:37

jimbe

総合スコア12646

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nvOSji1879

2022/10/30 03:30

回答ありがとうございました。おっしゃる通り、"必ず"を保証できないケースも多々あるはずなので、保険的な考え方も持ち合わせて、基本的にはelseを書く考え方で、判断しようと思います。
guest

0

本来は

Java

1if( 条件式A ){ 2 // 処理A 3}else if( 条件式B ){ 4 // 処理B 5}else{ 6 // 処理C 7}

で一つだと思います。でも仕様によってはelseもelse ifも必要が無い場合もあります。

たとえば bool isWritten という変数があり、これの値がtrueのときに処理Aをそれ以外なら処理Bをする場合、

isWritten == true -> 処理A
isWritten == false -> 処理B

ですけど、これを上記の基本的なものに埋め込むと

Java

1if( isWritten == true ){ 2 // 処理A 3}else if( isWritten == false ){ 4 // 処理B 5}else{ 6 // 処理C 7}

となります。ですがbool型は trueかfalseしかありません。最初のif( isWritten == true )を満たさないのならもう一方の falseになっているはずです。二択のうちの一つが存在しないならもう、一択しかないですね。
ということはisWritten == trueを満たさない時点でisWritten == falseも決まったようなものです。
(言語によってはundefinedとかのような値になったりしますが、常に何らかの値が入っているという前提で)

trueじゃないならfalse, falseじゃないならtrueという感じなのでelseが出てくる理由はないですよね。
だって書いてもそこに到達するものないじゃないですか。

仮にbool isWritten = false;だとしたら、if( isWritten == true )は満たさないので、次のelse ifに。
else if( isWritten == false )は満たしますからelseには行きません。

でも、先ほど書いたように trueならfalseを満たさず、falseならtrueを満たさないという排他的な関係なので、
「else ifではなくelseで対応可能」となります。

なので

Java

1if( isWritten == true ){ 2 // 処理A 3}else{ 4 // 処理B 5}

と書けますね。isWritten == true を満たさないなら 値はfalseってことは確定だからelseでも対応可能ですね。

で、int型で複数の値になる場合 ( 選択肢が { 1, 2, 3, 4, ... } と複数あるとか )は else ifを使って分岐させる。

Java

1int a = 10; 2if( a == 1 ){ 3 // 処理A 4}else if( a == 2 ){ 5 // 処理B 6}else if( a == 3 ){ 7 // 処理C 8}...{ 9... 10}else{ 11 // 処理X 12}

でも変数に入っている値は「常に 1≦値≦10でないといけない」場合でもたとえばa = 130のような範囲外の値になっていたりすることもある。
そうなるとelse ifだけでは足りない。やるとしたらもう人間の手には負えません。
だって -1304213 とかみたいな値を入れられる可能性があるんですよ? マイナスだけじゃなくてプラスも。
面倒ですね。ということでelseを使って「今までの条件に該当しないなら」つまり、範囲外の値ならとする。

そしてこの値が文字列だとどうでしょうか?「はろー」「ぐっばい」…といろんな候補があるのでその分岐のためにelse ifを使う。

だから基本は最初に挙げたelse ifとelseも使ったヤツで、必要な分使っていけばいいということです。

投稿2022/10/30 01:36

BeatStar

総合スコア4958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nvOSji1879

2022/10/30 02:26

詳しいご回答ありがとうございました。boolean型の箇所の説明がわかりやすく納得いきました。基本は、if-else if -else文で考えて、不要な場合は、分岐条件を変えたいと思います。
nvOSji1879

2022/10/30 03:35

あと、記載していただいたコードを見て、選択肢(条件分岐)が2択の場合は、trueかfalseで判断したほうがわかりやすかったので、条件に何を使用するかは、仕様に応じて変えたいと思います。
BeatStar

2022/10/30 04:08

なんでもかんでもtrue/falseでやると可読性が悪くなるので必要に応じて使ってくださいね。
guest

0

else ifは高い拡張性を有する。

投稿2022/10/29 17:23

atcoderyellow

総合スコア481

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問