1

I'm attempting to ask the user for a double value, using Scanner.nextDouble(); but I'm getting a NoSuchElementException before I have a chance to type anything. From what I can see in the documentation, this means that Scanner is at the end of the input. However, I don't understand how that can happen when the Scanner is reading from System.in, not a file.

Is it possible that having other Scanners open is causing this? I don't think that should be the case, as another method is successfully run before this code that opens and closes another Scanner. But I don't really know enough about the ins and outs of Scanner (or much else!) to know if that is the issue.

Here's where I'm at currently, after a lot of failed attempts to re-write this code to get it working:

public static double collectDepositAmount(int accountNum){
    System.out.print("Enter how much you would like to deposit in Account #" + accountNum + ": $");
    Scanner userInput = new Scanner(System.in);
    double finalDeposit;
    try{
        double inputDeposit;
        inputDeposit = userInput.nextDouble();

There's more after that, but the exception always gets thrown at userInput.nextDouble();. The catch block is only looking for InputMismatchException, and I close userInput right before I return a valid double.

Irish Jet
  • 11
  • 1
  • This famous issue occurs when closing a `Scanner` instance created on `System.in` also closes `System.in` so the user input cannot be read afterwards. – Nowhere Man Nov 16 '21 at 22:15

1 Answers1

1

Either you closed System.in, or, the next token isn't parsable as a double. It could be either issue; they'd both result in a NoSuchElementException.

You closed System.in

Perhaps you closed it before ever calling this code (which doesn't close System.in, fortunately), which is easier than you might think. This will do it:

try (Scanner s = new Scanner(System.in)) {
 // stuff here
}

After that try block is done, System.in is now closed (solution: Don't close System.in; don't close anything that you wrapped around System.in either).

There's no double there

It could also simply be that the next token available is not a double, then you also get this exact same behaviour. To 'detect' that, call .next() instead, see if you do get something (and, what that is, for example by printing it). Could be that you're entering 5,20 and the system was expecting you to use dots for decimal separators (e.g. 5.20) instead, thus concluding the next token isn't a double, and throwing that same exception.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • So, closing a Scanner reading from System.in closes System.in itself? Does this mean I should never close a Scanner that reads from System.in? – Irish Jet Nov 16 '21 at 22:32
  • @IrishJet Yup. Never close those scanners. Unfortunately IDEs these days tend to ship with fairly extensive linting configured out of the box (linting = marking lines of code off as bad code style / dangerous) and they can mark that off as 'dangerous'. Ignore those linters; the java ecosystem as designed can't actually correctly determine when resources should be closed and when they should not. System.in being a fine example of that. – rzwitserloot Nov 16 '21 at 22:45