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

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

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

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

Q&A

3回答

4693閲覧

if文を通らない理由がわかりません

kanekoK

総合スコア11

Java

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

0グッド

1クリップ

投稿2021/05/03 11:42

java

1import java.io.*; 2import java.util.*; 3public class Main{ 4 5 public static void main(String[] args) throws IOException { 6 Aisatsu aisatsu = new Aisatsu(); 7 aisatsu.execute(); 8 9 while(true){ 10 MenuHyouji menu = new MenuHyouji(); 11 menu.execute(); 12 13 System.out.println("メニュー番号を選んでください"); 14 Scanner scan = new Scanner(System.in); 15 String str = scan.next(); 16 17 if(str.equals("1")){ 18 KaisyaJyouhou kaisyaJyouhou = new KaisyaJyouhou(); 19 kaisyaJyouhou.execute(); 20 continue; 21 } 22 23 if(str.equals("2")){ 24 HajimeteUser muryouSample = new HajimeteUser(); 25 muryouSample.execute(); 26 continue; 27 } 28 29 30 } 31 } 32}

java

1import java.io.*; 2import java.util.*; 3 4class HajimeteUser{ 5 public HajimeteUser(){ 6 7 } 8 9 public void execute()throws IOException{ 10 System.out.println("yes/no"); 11 Scanner scan = new Scanner(System.in); 12 String str = scan.next(); 13 14 while(true){ 15 16 if(str.equals("yes")){ 17 System.out.println("住所を入力してください"); 18 String adress = scan.next(); 19 if(adress.equals("1")){ 20 System.out.println("住所を登録しました"); 21 break; 22 }else if(adress == null){ 23 System.out.println("住所は必須です"); 24 continue; 25 } 26 } 27 if(str.equals("no")){ 28 break; 29 } 30 } 31 } 32 } 33

上記実行すると、
}else if(adress == null){
System.out.println("住所は必須です");
continue;
}

入力しないでエンターを押すと上記のif文を通らないのですが、理由がわかりません。
教えていただきたいです。

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

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

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

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

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

guest

回答3

0

色んな考慮がされてない実装なので、自由入力を許す場合、いきなり書くのではなくフローチャートなど用いてケースパターンを洗い出すことを強くすすめます。

一番最初の入力でも考えることは沢山あります。
yes、no以外入力されたらどうなるか?
YesやNoだとどうなるか?
yesが来たとして、 1以外だとどうなるか?

となると「while(true)に入るタイミングが適切か」というのも見えてくるはず。

既に指摘されているように「分岐を通らないのはなぜか」を調べるのは大事なことなのですが、「どこまで考慮された設計となっているか」のほうが大事です。

ユーザーは何を入力するかアプリケーションは知りません。
ユーザーの入力は信用してはいけません。
「モンキーテスト」という工程もあるくらいです。
正常系は通って当たり前で、異常系をどれだけ設計時に考慮できるかで実装の粒度も精度も変わってきます。そのままアプリケーションの質にもかかわります。

別に「設計」といってもそこまで大それたことはしなくていいと思います。
先に書いたフローチャートのようなものに補足を入れたものでも十分です。
手書きメモレベルでもいいです。

今回だと「どういう入力があるか」「どういう入力があった時にどうするか」という点を重点的に考えてください。

もう少し具体的に言うと、
if-elseifだけではなくelseも考えることです。
ホワイトリスト、ブラックリストで言うと、今回は「ホワイトリスト」を採用することになると思います。
つまり、「許可している入力以外はNG」とするわけです。

もう少し細かく考えていくと今回「なぜ想定の場所を通っていないか」も見えてくるはずです。

「実装の考慮が足りない」のが本質。
「値の確認の仕方(デバッグの仕方)を身に着けていない」というのが手持ちスキルの問題。これに「改行、空文字、nullの違いなどの理解」も含みますかね。

直面している問題を解決するだけならすぐですが、
それ以前に理解していないと結局同じところに戻ってくるのは間違いないので、
ここでしっかり理解されるよう、強くすすめます。

書いたとおりにしか動かないプログラミングにおいては
「惜しい」というのは存在しません。true(できた)かfalse(できてない)かだけです。
時には今書いてきたコードを一旦捨てて全部書き直すようなことも必要です。
「あとちょっとなのに」を繰り返すと穴だらけのコードを助長するだけという事態も起きます。
なので実装に入る前の設計が大事なのです。

投稿2021/05/03 20:52

m.ts10806

総合スコア80850

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

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

0

入力しないでエンターを押すと

エンターを入力しているので、改行コードだけ入った文字列が取れます。

投稿2021/05/03 11:46

maisumakun

総合スコア145183

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

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

kanekoK

2021/05/03 12:02

入力がなかった場合の条件式にするにはどうしたらいいでしょうか?
y_waiwai

2021/05/03 12:06

実際に入力がなかったときにはどういう文字列が取ってこれるのか見てみればどうでしょうか
kanekoK

2021/05/03 12:12

文字列は何も返ってきませんでした。 ↓実行結果 住所を入力してください
kanekoK

2021/05/03 12:12

空行ができるのみでした
maisumakun

2021/05/03 12:14

最初に書いたように、それが「改行コードだけ入った文字列」です。
kanekoK

2021/05/03 12:17

System.out.println("住所は必須です");を 表示するにはどう変更したらいいでしょうか?
y_waiwai

2021/05/03 12:17

そのなにも帰ってこないように見える文字列に、どういう「文字」が含まれてるのか表示してみたらどうですか?
kanekoK

2021/05/03 12:19

それはどのように確認できますか?
guest

0

}else if(adress == null){

これはadressというオブジェクトが存在しないということを指しています。
この「オブジェクトが存在しない」ということと「文字が1文字もない」ということは別物です。
今回はScannerクラスからのメソッドの戻り値を受け取っているのでオブジェクトは存在しています。
ですので、1文字も入力されていなくてもオブジェクトは存在するので、このelse if文は通らないわけです。

なので、チェックすることはオブジェクトの有無ではなく、オブジェクト内部に格納されている文字列についてです。

Stringクラスに入っている文字の長さは以下のメソッドで確認できます。
int length()

また、文字が格納されているかどうかは以下のメソッドで確認できます。
boolean isEmpty()

これで修正の仕方はわかるかと思います。

投稿2021/05/03 16:19

rinjinto

総合スコア170

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

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

rinjinto

2021/05/03 16:25

あと、質問とは違いますが、Scanner.next()の使い方が正しくないです。 Scanner.hasNext()の戻り値をチェックしてtrueの時のみnext()で取り出すようにする必要があります。 万が一、取り出すオブジェクトが存在しない場合、NoSuchElementException例外が発生します。 個人的には上記処理をしつつ、next()してる箇所をtry catchで例外処理コードを実装しておいたほうがいいと思いますが。
m.ts10806

2021/05/03 21:23

>adressというオブジェクトが存在しない 単にnull代入したときもなので一概に「オブジェクトが存在しない」と言えないようには思いますが、意図したところと違ったらすみません。
rinjinto

2021/05/03 23:55 編集

adressにnullを代入するという意味がわかっていますか? それは「adressのオブジェクトを削除する」という意味ですよ。 "null"というのはJavaでは"オブジェクトがない"ということを意味します。
m.ts10806

2021/05/04 00:31

「削除する」となるとまた御幣が出そうな気がします。 「削除する」と明示されている公式の資料があればまた別ですが。。
rinjinto

2021/05/04 01:11 編集

質問者の方だと思っていました。 初心者の方相手だと思っていたので、簡単な理解である「オブジェクトが存在しない」「削除する」という記載をしました。 ご理解いただいていると思いますが、オブジェクト参照にnullを代入するということは「参照するオブジェクトをなくす」、ポインタ的な考え方でいえば「オブジェクトの参照アドレスをnullアドレスに設定する(nullアドレスにオブジェクトは存在しない)」ということになります。 「参照するオブジェクトをなくす」ということと、元々代入されていたオブジェクトが非参照になってガベージコレクション対象となること(他に参照がないという条件)をまとめた意味として「オブジェクトを削除する」という記載をしました。 厳密にいえば意味が違うとは思いますが、初心者の方相手にはここまで厳密な理解は不要で概念的な記載で十分ではないでしょうか? (注:プログラムである以上、どんな言語であってもアドレスとは無縁ではないのでjavaであってもポインタ的な思考は活用可能)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問