The Scanner class contains several gotchas that are not documented, which is unfortunate considering how heavily the class is used. Often developers are left to create their own wrapper class to smooth over most of the bumps. I have a KeyboardUtility that does this. Cambell Ritchie has a similar one he created. These solve the problem of only having a single Scanner from System.in for an entire project, and deal with other issues like leftover pending new-lines in the input stream. They also provide a framework for prompting the user and input validation. Piped input streams can be handled with a few of the low level wrappers but the bulk of the methods are intended for user keyboard input. You're welcome to borrow this code.
The documentation does say that the nextLine() method can throw NoSuchElementException. So that's what there is to understand -- it can happen according to the documentation, and it did happen.
But as others have already said, you shouldn't expect the documentation to go into details of specific instances of a class. And really your code isn't specific to System.in, either. It shouldn't be hard to write similar code which uses two Scanners over the same String, for example.
In order to understand it, you need to understand what System.in is. System.in is a static input stream variable. It does not get instantiated by the developer, and there's only one instance of it that ever exists. Therefore when you create two Scanners pointing at System.in, they are both pointing to the same input stream.
So when you close that one input stream, both Scanners that use the input stream can no longer process data from it.
It is not documented in Scanner - and it should not be, because it's not a behavior of Scanner. It's a behavior of System.in. If you use System.in in any other class that uses an Input Stream and you close it, it'll do the same thing.
Campbell Ritchie wrote:But System.in always implicitly might have a next line; as soon as you push any key that next line will exist and hasNextLine() will return true. So...is going to behave as an infinite loop.
What interests me is the scanners are on seperate instances , are new and not static.
The STDIN and STDOUD are in effect static as there is only one OS and computer so in effect the two scanner references are of something that never closes anyhow.
Only say STDIN/STDOUT/STDERR (remember there are three “standard“ streams) if you are writing C.
Yes, the three streams are declared as static fields in the System class; it is possible to close any one of them, which OP is doing in this case by calling close() on a Scanner object.
Yes, you could use two Scanner objects, but what's the point? They are both pointing to the same input and there is a risk of them interfering with each other about which token comes next. Also Scanners aren't thread‑safe. If you use close one Scanner, then as Zachary Griggs said,
. . . when you close that one input stream, both Scanners that use the input stream can no longer process data from it. . . .
No thanks. We have all the government we need. This tiny ad would like you to leave now:
SKIP - a book about connecting industrious people with elderly land owners