Here's a reduced version of the code that's throwing the exception.
static String s1;
static String s2;
static void getString(String s) {
Scanner sc = new Scanner(System.in);
s = sc.nextLine();
sc.close();
}
public static void main(String[] args) {
getString(s1);
getString(s2);
}
Exception in thread "main" java.util.NoSuchElementException: No line found at java.util.Scanner.nextLine(Scanner.java:1540) at temp.Temp.getString(Temp.java:13)
I'm calling the getString
method twice, and on second call it breaks on:
s = sc.nextLine();
Now, I understand that removing the sc.close()
line solves the problem (and making sc
a static variable probably, too). What I need to grasp is WHY this is the case.
I read the specification of the scanner
class but couldn't deduce. I also read several posts on this exception including this one, which says that closing the scanner also closes the underlying stream. But I'm creating a new scanner and reopening the stream with every method call, no?
There is no such thing as "reopening a stream". The only thing you can do is create a new stream, with a new Scanner
, and optionally place it in the same variable.
Once you close sc
, you also close the underlying System.in
stream. Creating a new Scanner
on top of it can't "reopen" it, and since the stream is closed, you get this exception.
To make a long story short - while it's definitely a good practice to close resources when you're done with them, you shouldn't close System.in
(or any scanner based on it).