Hello, Everyone, I am currently learning Java. As a beginner, I worked with console IO. To read input from the terminal, I use the Scanner class.
I tried a mini CLI project, so I used the Scanner object in different classes. For resource management, the Scanner object — especially when reading from sources like System.in or files — utilizes underlying system resources (like file descriptors or input streams). Closing the Scanner explicitly releases these resources back to the operating system, preventing resource leaks.
So, I closed the Scanner in each class, but after running my program, I got this exception:
Exception in thread "main" java.util.NoSuchElementException
This was the first time I saw this exception. After reading some related S…
Hello, Everyone, I am currently learning Java. As a beginner, I worked with console IO. To read input from the terminal, I use the Scanner class.
I tried a mini CLI project, so I used the Scanner object in different classes. For resource management, the Scanner object — especially when reading from sources like System.in or files — utilizes underlying system resources (like file descriptors or input streams). Closing the Scanner explicitly releases these resources back to the operating system, preventing resource leaks.
So, I closed the Scanner in each class, but after running my program, I got this exception:
Exception in thread "main" java.util.NoSuchElementException
This was the first time I saw this exception. After reading some related Stack Overflow discussions, I understood the real reason.
The Core Problem: Input Stream Closure
When a Scanner is closed, it also closes the underlying input stream it’s connected to. For example, if you create a Scanner from a FileInputStream, closing the Scanner will also close that FileInputStream. This ensures that all related resources are properly shut down.
But I wondered:
“If I create a new Scanner again, shouldn’t the JVM reopen the input stream?”
Surprisingly, no — and here’s why.
Example Code
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan1 = new Scanner(System.in);
String ip1 = scan1.next();
scan1.close();
Scanner scan2 = new Scanner(System.in);
String ip2 = scan2.next();  // throws Runtime exception
scan2.close();
}
}
Output:
Exception in thread "main" java.util.NoSuchElementException
What Actually Happens Under the Hood
- System.in is a singleton InputStream provided by the JVM — not something that can be reopened automatically.
 - When you call 
scan1.close(), it callsSystem.in.close()internally. - This closes the standard input stream permanently for that JVM session.
 - Any subsequent Scanner (like 
scan2) tries to read from a closed input stream, so the JVM throws a NoSuchElementException or IllegalStateException. 
So even though you created a new Scanner, it still points to the same closed System.in, not a fresh one.
What’s the Correct Practice?
If you’re reading from System.in, never close the Scanner until your entire program finishes reading all input. You can safely reuse the same Scanner across methods or classes by passing it as a reference — but avoid closing it.
Example fix:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String ip1 = scan.next();
String ip2 = scan.next();
scan.close();  // Close only once at the end
}
}