javajava.util.scannernosuchelementexceptionsystem.in

NoSuchElementException on reopening the scanner within a method


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?


Solution

  • 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).