Javaの Scanner クラスを使うときに、一度 Scanner のインスタンスを作成して close() した後、再度 Scanner を作成すると、文字列が入力できなくなることがあります

こんにちは。ゆうせいです。

Javaの Scanner クラスを使うときに、一度 Scanner のインスタンスを作成して close() した後、再度 Scanner を作成すると、標準入力(System.in)から文字列が入力できなくなることがあります。この現象の主な原因は、System.in が閉じられてしまうため です。


なぜ Scanner を閉じると問題が起きるのか?

Scanner のインスタンスを System.in を使って作成すると、内部で System.in を利用する InputStream を管理します。そして、Scanner.close() を呼び出すと、System.in一緒に閉じられてしまう のです。

Scanner scanner1 = new Scanner(System.in);
System.out.println("何か入力してください:");
String input1 = scanner1.nextLine();
System.out.println("入力された文字列: " + input1);
scanner1.close(); // System.in も閉じられる

Scanner scanner2 = new Scanner(System.in); // 新しい Scanner を作る
System.out.println("もう一度入力してください:");
String input2 = scanner2.nextLine(); // ここでエラーまたは入力不可になる
System.out.println("入力された文字列: " + input2);
scanner2.close();

実行時の問題

  • scanner1.close() の時点で System.in も閉じられる
  • scanner2.nextLine() の時に System.in がすでに閉じられているため、入力が受け付けられない
  • 場合によっては java.util.NoSuchElementException が発生する

解決策

Scanner を閉じない(close() を呼ばない)

通常、System.in を使う Scanner はプログラムの最後まで閉じないのがベスト です。close() しなくてもプログラム終了時に System.in は自動的に解放されます。

Scanner scanner = new Scanner(System.in);
System.out.println("何か入力してください:");
String input1 = scanner.nextLine();
System.out.println("入力された文字列: " + input1);

System.out.println("もう一度入力してください:");
String input2 = scanner.nextLine();
System.out.println("入力された文字列: " + input2);

scanner.close(); // 最後に閉じる


Scanner を使わずに BufferedReader を使う

BufferedReaderclose() しても System.in を閉じないため、複数回の入力が可能です。

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("何か入力してください:");
        String input1 = reader.readLine();
        System.out.println("入力された文字列: " + input1);

        System.out.println("もう一度入力してください:");
        String input2 = reader.readLine();
        System.out.println("入力された文字列: " + input2);
    }
}


まとめ

  • Scanner.close() を呼ぶと System.in も閉じられ、再度 Scanner を作っても入力できなくなる。
  • 解決策としては、Scanner を最後まで閉じないか、BufferedReader を使う方法がある。
  • System.in を閉じると復活できないので、標準入力を使うプログラムでは close() のタイミングに注意すること!

これで問題は解決できるはず!試してみてね。

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。