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

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

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

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

Q&A

解決済

3回答

7065閲覧

このプログラムでIllegalArgumentException:nullです、が出てしまわないように、 対応したいです

gyro16

総合スコア89

Java

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

0グッド

0クリップ

投稿2016/10/20 02:28

編集2016/10/20 05:08

###前提・実現したいこと
このプログラムでIllegalArgumentException:nullです、が出てしまわないように、
対応したいです。
nullが与えられる入力がされた場合、例外処理以外で対応するにはどうすべきのなのでしょうか?

String ip がnull判定される入力があるらしいのです

###発生している問題・エラーメッセージ

IllegalArgumentException:nullです

###該当のソースコード

java

1import java.util.*; 2 3public class Main{ 4 public static void main(String[] args){ 5 Scanner bScanner = new Scanner(System.in); 6 if(bScanner.hasNextLine()){ 7 int number = bScanner.nextInt(); 8 if((number > 0) && (number <= 100)){ 9 String[] ips = new String[number]; 10 for(int i = 0; i < number; i++){ 11 Scanner aScanner = new Scanner(System.in); 12 if(aScanner.hasNextLine()){ 13 ips[i] = aScanner.nextLine(); 14 } 15 } 16 17 for(String ip : ips){ 18 if(ip != null){ 19 String[] nums = ip.split("\\."); 20 if(nums.length != 4){ 21 System.out.println("False"); 22 continue; 23 } 24 boolean flg = false; 25 for(String num : nums){ 26 if(num.equals("")){ 27 flg = false; 28 break; 29 } else{ 30 int n = Integer.parseInt(num); 31 if((n >= 0) && (n <= 255)){ 32 flg = true; 33 } 34 } 35 } 36 String msg = (flg)? "True" : "False"; 37 System.out.println(msg); 38 } else{ 39 throw new IllegalArgumentException("nullです"); 40 } 41 } 42 } else{ 43 throw new IllegalArgumentException("値が不正です"); 44 } 45 46 } 47 } 48} 49

###試したこと
課題に対してアプローチしたことを記載してください

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

テストケースを受けるだけの立場ですのでテストケースで何が投げかけられているかは分かりません。

ただScannerが、そもそもこのプログラムでも、

特に明記されていないかぎり、nullパラメータをScannerのいずれかのメソッドに渡すと、NullPointerExceptionがスローされます。

なのでScannerのnullを除去または対応したいです。

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

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

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

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

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

swordone

2016/10/20 02:33

どういう入力を入れたらそうなりましたか?
退会済みユーザー

退会済みユーザー

2016/10/20 04:03

だれかにもいったが「IllegalArgumentException」は不正な引数の時に投げる例外です。 正常に使ってください
guest

回答3

0

throw new IllegalArgumentException("nullです");しなければ例外はスローされませんが、、、
ipがnullなら処理をスキップすればいいのではないでしょうか?
一番簡単なのはコメントアウトしてしまえばいいです。

//throw new IllegalArgumentException("nullです");

投稿2016/10/20 02:33

編集2016/10/20 02:34
moonphase

総合スコア6621

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

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

gyro16

2016/10/20 04:37

if(ip != null){ を外すとNullPointerExceptionが出ます。 for(String ip : ips){ String[]ipsからString ipを取り出す時に、ipがnullになることがあるようです。 入力テストケースは公開されていないため、何が入力に投げかけられているかは分かりません。 IPアドレス群String[]ipsとIPアドレスString ipで、 \\.がデリミタ区切り記号です。
moonphase

2016/10/20 04:50

if(ip != null){を外すのではなく、throw new IllegalArgumentException("nullです");を外すのです。 入力データが処理できない場合は以下の対応が基本かと思います。 gyro16さんはどうしたいのですか? 1.SKIPして処理を続ける 2.エラーを出して処理を停止
gyro16

2016/10/20 05:04

それは分かっていますがコメントアウト、それでは根本解決になりません。
moonphase

2016/10/20 05:08

gyro16さんはどうしたいのですか?次の中から選んでください 1.SKIPして処理を続ける 2.エラーを出して処理を停止 3.その他
moonphase

2016/10/20 05:20 編集

補足で追加しておきますが、ipがnullで入ってくることが予めわかっているのなら、それをどう処理するか設計で決定することかと思います。 その設計に従って実装するだけですので、どうするか決まらないと回答もできません。 繰り返しとなりますが、対応をもう少し詳しく書くと 1.処理できないデータは行番号をログに記録して、SKIPして処理を続ける 2.処理できないデータがあった場合、行番号をログに記録して、処理を中止する 3.処理できないデータは何らかのダミーデーターに置き換えて処理する(例えば0.0.0.0等) 一般的に入力データにエラーが有る場合は「スキップ」「停止」「データ置き換え」で対応するしかありません。 処理できないデータは if (ip == null) で判定できますので、その際に対応したい処理を書けばよいかと思います。 もう一つの方法として、このプログラムの前段階で入力データの検証を行い、 検証で問題があれば、1.処理を停止 2.処理できないデータを処理できるダミーデータに置き換える 3.処理できないデータを省く などの処理を行ってからこのプログラムに渡してあげる などの対応方法があります。
guest

0

ベストアンサー

テストケースを受けるだけの立場ですのでテストケースで何が投げかけられているかは分かりません。

思うにここがポイントです。あなたが何かをテストするために書いたプログラムはmainメソッド全部でしょうか?もしそうなら別のプログラムが生成した出力を標準入力から読み込んで内容をチェックするためのテストプログラムのはずです。そうであれば

  • 入力のテストケースはこれこれである
  • パスする条件はこれこれである
  • このテストプログラムはテストがパスしたかどうかでこれこれの出力をする

というテストプログラムの仕様を言えるはずなので、入力のケースがわからないということはありえないと思います。そこが回答者を混乱させている原因と思います。ひょっとしたらあなたも混乱しているのかもしれません。ご自分がすべき仕事の内容を今少し明確に述べるべきです。

それはさておき、このプログラムが行っていることだけに注目してプログラムの論理がおかしいところを推測することは可能です。このプログラムが想定する入力仕様を推測すると例えば次のようなもののはずです。

  1. 入力は任意個数のブロックからなる
  2. 各ブロックはN+1行からなる
  3. 各ブロックの先頭行にはそのブロックに含まれている行数Nを示す整数がある

...

もしこの推測通りなら1.~3.についてエラーケースとして考えられるのは以下のようなものです。

A. (区切り文字を除いた)ブロックの先頭に整数がない
B. ブロックの先頭の整数(=N)が0以上100以内の範囲にない
C. ブロックの先頭以外の行がN行なかった(N行読み込む前にファイルの終端に達した)
...

このプログラムの処理と見比べるとあやしいと思われる点があります。(仕様如何で問題かどうかは変わるので単にあやしいといえるだけですが)

(1) ブロックの先頭に整数がなかった場合に別の例外が発生する
(2) Bをパスしなかった場合にIllegalArgumentExceptionをthrowしている
そういう仕様ならいいですが、"nullです"という例外を投げていけないならこの例外もダメでは?と思えてきます。
(3) Cをパスしない場合の論理に矛盾がある
hasNextLineがfalseになってもエラーとしていないことから「行がある間はデータを読み込むが必要行数以下でもエラーにしない」と読めますが、一方forループでは「必ずN行ある」と想定した処理になっています。

(3)について「N行以下しかデータがない場合も許容する」ならばfor文の処理対象要素の入れ物に固定的な大きさで生成した配列(つまりnew String[number]している配列)を用いることはおかしいです。配列ではなくListなどにして読み込めた行のデータのみをforループの処理対象にすべきです。
(3)について「N行以下しかデータがない場合を許容しない」ならばhasNextLineメソッドがfalseになった瞬間に直ちにエラー処理をすべきです。もし「読み込めた行の範囲内で各行のチェックもしたい」のであればやはり配列ではなくListを用いるべきです。

投稿2016/10/20 06:44

編集2016/10/20 06:47
KSwordOfHaste

総合スコア18392

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

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

swordone

2016/10/20 06:59

後半は多分気にしなくていいかと。状況はおそらくpaizaかなにかの問題を解こうとしているのでは? それなら入力は具体的に何が流れてくるのか分からないですし。
KSwordOfHaste

2016/10/20 07:07

なるほど、そういうものがあるんですね・・・しかしもしそうならこんな回答したのはなんだか・・・
gyro16

2016/10/20 08:34

丁寧にありがとうございます。 やはり配列で行き詰まりますね。リストで対応します。
guest

0

特に明記されていないかぎり、nullパラメータをScannerのいずれかのメソッドに渡すと、NullPointerExceptionがスローされます。

これの意味するところは、Scannerが持つ各メソッドが参照型の引数(Stringなど)を要求している場合、その箇所にnullを渡すな、渡すとNullPointerExceptionになるぞ、ということです。
例えば、デフォルトて半角スペースに設定されている区切り文字を変更する場合に使うuseDelimiter(String)というメソッドがあります。この引数としてnullを渡すと、個別のメソッドの説明には書かなかったけどNullPointerExceptionになるよと言うことです。
このコードにおいてScannerのメソッドにnullが渡る可能性のある場所は存在しないので、気にする必要はありません。
NullPointerExceptionの本質は、nullであるべきでない場所がnullになっているというバグです。だから、NullPointerException(を始めとしたRuntimeException系の例外)をキャッチしてはいけないと言われるのです。キャッチしてしまうと、バグに気づきにくいからです。

投稿2016/10/20 06:39

編集2016/10/20 06:54
swordone

総合スコア20649

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問