Search code examples
javainputiouser-input

Why does closing a scanner seem to break new scanners?


import java.util.Scanner;

public class Foo {
    public static void main(String[] args) {
        Foo foo = new Foo();
        foo.getNextToken();
        foo.getNextToken();
    }

    public void getNextToken() {
        Scanner s = new Scanner(System.in);
        while (true) {
            if (s.hasNext()) {
                System.out.println(s.nextLine());
                //s.close();
                return;
            }
        }
    }
}

When I try to run the above code, it works as you might expect. Every time I insert a line, the computer pastes the next line.

enter image description here

However, if I uncomment out the s.close() line, and run again, I get the following behavior:

enter image description here

For some reason, the hasNext() method continuously returns false despite the fact that there is very obviously a next argument. I tried a lot of things and I can't find any workaround. for example if I change the code to just

public void getNextToken() {
        Scanner s = new Scanner(System.in);
        System.out.println(s.nextLine());
        s.close();
        return;
    }

Then, again, it works for the 1st statement, but then instantly gives a NoSuchElementException. Of course, if you don't close the 1st scanner, it works fine.

I don't see why closing 1 scanner should affect the other, but I've heard that it's bad practice not to close scanners, and more importantly, there's an annoying yellow error message if I don't. Can anyone tell me of a way to fix this, and why it happens? I could pass in the scanner as an argument in the main method and also close it there but that just seems a bit messy.


Solution

  • Because you closed System.in. Don't do that. Don't close the scanner. Don't create new ones either. Just keep using the same one. It will still work.

    Using multiple scanners on the same underlying input really is bad practice. You will lose data.