「Scannerクラスは閉じなくてもいい?実は知らない“閉じるべきケース”とその理由」
こんにちは。ゆうせいです。
今回はJavaでよく使う Scanner
クラスについて、「閉じる必要があるのか?」という疑問に答えていきます。
たしかに、「Scannerは閉じなくても問題ない」と言われることが多いですが……
本当にそうでしょうか?
実は、場合によっては閉じる必要があるんです!
まずScannerクラスとは?
Scanner
クラスは、標準入力(キーボード)やファイルなどからテキストを読み取るためのクラスです。
たとえば、こんなふうに使いますね。
Scanner sc = new Scanner(System.in);
System.out.println("名前を入力してください:");
String name = sc.nextLine();
基本的には「閉じなくても動く」
System.in
から入力を受け取る場合、たとえ sc.close()
を書かなくても、プログラムは動きます。
だから、
sc.close();
を省略してもエラーにならないわけですね。
でも、閉じたほうがいい場面は確実にある!
閉じるべきケース:ファイルやネットワークを読み取るとき
Scanner sc = new Scanner(new File("data.txt"));
このようにファイルを読み込む場合、Scanner
はファイルのリソース(メモリやファイルハンドル)を保持します。
→ 閉じないと、メモリリークやファイルが開きっぱなしになる可能性があります。
対処法:
try (Scanner sc = new Scanner(new File("data.txt"))) {
while (sc.hasNext()) {
System.out.println(sc.nextLine());
}
}
// 自動的に閉じられる(try-with-resources)
閉じるべきではないケース:複数回Scannerを作成しているとき
Scanner sc1 = new Scanner(System.in);
Scanner sc2 = new Scanner(System.in); // これ危険!
// sc1かsc2のどちらかでSystem.inを閉じると、他方は使えなくなります
解説:System.in
はJava仮想マシン(JVM)で共有されています。
どれか1つの Scanner
が System.in
を閉じてしまうと、以降の入力ができなくなる危険性があります。
結論:閉じるかどうかの判断基準
使用対象 | 閉じる必要 | 理由 |
---|---|---|
System.in | 原則不要 | JVMで共有されているため。閉じると再入力不可になる |
ファイル入力 | 必須 | リソースを明示的に解放する必要がある |
ソケット/ネット通信 | 必須 | 通信が閉じずに残ると、接続が維持され続ける |
最後に:おすすめの書き方
System.in
を使うときは、Scannerを閉じずに1つだけ作って最後まで使うのがベストです。
ファイルやネットワークの場合は、try-with-resources
構文を使って自動で閉じるようにしましょう!
try (Scanner sc = new Scanner(new File("data.txt"))) {
// 安心安全な書き方
}
今後の学習の指針
このテーマに関連して、さらに理解を深めるには以下がおすすめです。
- try-with-resources構文の使い方
- Javaのリソース管理(メモリ・ファイル)
- InputStreamとBufferedReaderとの違い
「なんとなく動くからヨシ!」ではなく、なぜ閉じる必要があるのか?を意識して、より一歩進んだJavaプログラマを目指しましょう!
セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク
投稿者プロフィール
