JavaのScanner使い方|標準入力・nextLineの罠・例外対策まで
CONTENTS
まず、JavaのScannerクラスは、標準入力(キーボード)やファイルなどのテキスト入力を、文字列・数値として手軽に読み取れる便利なAPIです。
さらに、本記事では、Scannerの基本概念から、next/nextLineの違い、数値入力・例外対処、ファイル読み込み、実践コード例までを一通り整理します。
そのため、「入力で詰まりやすいポイント」と「安全に書く型」を押さえて、すぐに使える形で理解することを目標にします。
また、Javaの全体像から整理したい場合は、エンジニアを目指す人必見!Javaとは?わかりやすく特徴と用途を解説も合わせて読むと理解が早まります。
さらに、Java学習を継続して伸ばす戦略まで知りたい場合は、エンジニアがJavaで成長するためのステップアップ戦略も内部リンクとしておすすめです。

一方で、一次情報としてはOracle公式のJavadocが最も確実です。
そのため、仕様を確認したい場合は、以下の外部リンクも合わせて参照してください。
Scannerとは何か
まず、Scannerはテキストを「区切り文字(delimiter)」でトークンに分割し、文字列やプリミティブ型へ変換して取り出すためのクラスです。
さらに、入力データを区切り文字で分割した「トークン」の列として扱います。
したがって、デフォルトの区切り文字は空白(スペース、改行、タブなど)なので、最初は「空白で区切られた単語や数値を順番に読むもの」と捉えると理解しやすいです。
例えば、nextIntやnextDoubleなどは、トークンを取り出したうえで数値に変換します。
しかし、変換できない形のトークンに当たると例外が起きます。
そのため、入力が崩れる可能性がある場面ではhasNextIntのような事前確認が重要になります。
一方で、Scannerは入力待ちで処理が止まることがあります。
つまり、プログラムが固まったように見える典型原因は「次のトークンが来るまで待っている」状態です。
したがって、読み取り単位(トークンか行か)と終了条件(EOFや終了文字)を最初に決めるのが実務的なコツです。

Scannerを使う準備(importとインスタンス化)
まず、Scannerはjava.util.Scannerにあるため、先頭でimport java.util.Scanner;が必要です。
さらに、IDEを使っている場合は自動補完で入ることもあります。
しかし、学習段階では自分で書けるようにしておくと混乱しません。
次に、どこから読むかを決めてScannerを生成します。
例えば、キーボード入力ならnew Scanner(System.in)、ファイルならnew Scanner(new File("path"))のように入力元を渡します。
そのため、同じ入力元に対して複数のScannerを乱立させるのは避けるのが無難です。
さらに、ファイル入力では読み終えたら確実にcloseする設計にすると、リソースリークやファイルロックのトラブルを予防できます。
したがって、後半で紹介するtry-with-resourcesを使うと、閉じ忘れをほぼゼロにできます。

標準入力(キーボード入力)の基本手順
まず、標準入力ではSystem.inを入力ソースにしてScannerを生成し、next系メソッドで値を取得して処理します。
さらに、基本の流れは「Scannerを作る → プロンプトを表示する → 読む → 処理する → 出力する」です。
そのため、プロンプトは「何を入力すべきか」を明確にし、入力ミスを減らすために効果があります。
例えば、整数を1つ読むなら、int n = sc.nextInt(); のように書けます。
一方で、nextIntは空白区切りの次トークンを整数として解釈します。
したがって、改行を含む入力でも同じように動きます。
しかし、実運用では入力が必ず正しいとは限りません。
そのため、hasNextIntで確認してから読む、エラー時はトークンを捨てて再入力させる、といった方針を決めると入力処理が安定します。
最小構成:整数を1つ読む
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("整数を入力してください: ");
int n = sc.nextInt();
System.out.println("入力された整数: " + n);
sc.close();
}
}
文字列を入力する(nextとnextLine)
まず、文字列入力は「トークン単位(next)」と「1行単位(nextLine)」のどちらで読みたいかを先に決めるのが重要です。
さらに、入力仕様が「スペースを含まない値の列」ならnext中心、「文章や住所のようにスペースを含む行」ならnextLine中心に寄せると事故が減ります。
そのため、混在する場合は読み取り順序も含めて設計しておくと安全です。

nextとnextLineの違い
まず、nextは区切り文字までの1トークンを返します。
例えば、入力がAlice Bobならnextは最初にAlice、次にBobを返します。
したがって、スペースを含む文字列は1回では取れません。
一方で、nextLineは「現在位置から行末まで」を返します。
例えば東京都 渋谷区のような入力でも、1回のnextLineでまとめて取れます。
そのため、空白を含む文章や住所のような入力に向いています。
nextLineが空文字になる原因(改行の扱い)
まず、典型例として、nextIntやnextでトークンを読んだ直後にnextLineを呼ぶと、nextLineが空文字を返すことがあります。
これは、nextInt/nextが「トークンの末尾まで」しか消費せず、その直後の改行文字は入力に残ったままだからです。
したがって、次に呼ばれたnextLineは「残っている改行まで」を1行として読み取り、結果として中身が空の行を取得したように見えます。
そのため、対処はnextLineの前に改行を消化することです。
例えばnextIntの直後にsc.nextLine();を1回入れて改行を捨て、その次のsc.nextLine();で本命の行を読むと安定します。
さらに、行単位に揃えたい場合は、最初からすべてnextLineで読み、必要な箇所だけ数値変換する方法もあります。
混在時の安全な型:改行を1回捨てる
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try (Scanner sc = new Scanner(System.in)) {
System.out.print("年齢を入力してください: ");
int age = sc.nextInt();
// 改行を1回消費(ここがポイント)
sc.nextLine();
System.out.print("名前を入力してください: ");
String name = sc.nextLine();
System.out.println("こんにちは、" + name + "さん。年齢は" + age + "歳です。");
}
}
}
数値を入力する(nextInt/nextDoubleなど)
まず、数値入力はnextInt、nextLong、nextDoubleなど、欲しい型に合ったnextXxxを使います。
さらに、これらは次のトークンを数値として解釈して返すため、空白区切りで並んでいる形式と相性が良いです。
そのため、学習用コードでは最短で動く形を作れます。
しかし、注意点は「範囲外」や「形式違い」です。
例えばintで受けるつもりが大きすぎる値が来た場合や、数値のつもりでabcが来た場合は例外になります。
したがって、現実の入力を扱うならhasNextIntで検証してから読む方針が安全です。
hasNextIntで事前確認し、合計を計算する
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try (Scanner sc = new Scanner(System.in)) {
long sum = 0;
System.out.println("整数を入力してください(整数以外で終了):");
while (sc.hasNextInt()) {
sum += sc.nextInt();
}
System.out.println("合計: " + sum);
}
}
}
入力エラー(例外)の対処(InputMismatchExceptionなど)
まず、nextIntなどで変換に失敗すると、代表的にはInputMismatchExceptionが発生します。
しかし、入力処理は「間違った入力をどう回復させるか」が品質を決めます。
そのため、例外を前提にした設計が実務では重要です。
さらに重要なポイントとして、例外が起きたとき、その原因となったトークンは消費されません。
したがって、そのまま同じnextIntを再試行すると同じ例外が繰り返されます。
そこで、sc.next()などで問題トークンを読み捨てるのが定石です。
例外時にトークンを捨てて再入力させる
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try (Scanner sc = new Scanner(System.in)) {
int value;
while (true) {
System.out.print("整数を入力してください: ");
try {
value = sc.nextInt();
break;
} catch (InputMismatchException e) {
System.out.println("数値として解釈できません。例: 10 のように入力してください。");
sc.next(); // 問題トークンを捨てる(ここがポイント)
}
}
System.out.println("入力された整数: " + value);
}
}
}
ファイル読み込みでScannerを使う
まず、Scannerは標準入力だけでなくファイルも読み取れ、行単位・トークン単位のどちらでも処理できます。
さらに、ファイル入力は入力が固定されるため、コンソールより再現性が高くデバッグしやすいのが利点です。
そのため、学習でも実務でも頻出のパターンです。
一方で、実務で重要なのは文字コードです。
そのため、UTF-8など仕様として文字コードを固定し、コンストラクタで明示するのが安全です。
さらに、存在しないファイルや権限不足などの例外も想定し、例外処理をセットで書くと堅牢になります。
1行ずつ読み込む基本形(UTF-8指定)
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
File file = new File("data.txt");
try (Scanner sc = new Scanner(file, "UTF-8")) {
while (sc.hasNextLine()) {
String line = sc.nextLine();
System.out.println(line);
}
} catch (FileNotFoundException e) {
System.out.println("ファイルが見つかりません: " + file.getAbsolutePath());
}
}
}
Scannerの要点まとめ

まず、Scannerの核心は「区切り文字でトークン化して読む」ことです。
さらに、nextはトークン、nextLineは行という読み取り単位の違いを意識し、どちらに揃えるかを先に決めると設計が安定します。
そのため、混在するなら「改行を1回消費する型」を入れるだけで、つまずきやすいバグを予防できます。
また、入力の信頼性が低い場合はhasNextXxxで検証し、例外時はトークンを捨てて回復する方針が有効です。
さらに、ファイル入力では文字コードを固定し、try-with-resourcesで確実にクローズすると運用が安定します。
つまずいたら、現役エンジニアと一緒に解決しよう
この記事で扱った【Java】は、独学だと細部で詰まりやすい分野です。さらに理解を深めたい方は、Zerocodeで実務直結の学習を進めてみませんか。
コード添削・詰まり解消を丁寧にサポート。
Java/SQL/Spring Bootを体系的に習得。
現場で刺さる成果物づくりを伴走。
時間と場所を選ばず学べます。