-2

I'm working on reading integers into a list in Java, and I found an exception that gets thrown when putting Scanner & nextInt() in the loop.

Exception gets thrown on the Scanner class in this code:

do{

        System.out.println("?");
        Scanner in = new Scanner(System.in);
        input = in.nextInt();
        in.close();
        if(input != SENTINEL)
        numberList.add(input);

    }while(input != SENTINEL);

Whereas moving the Scanner initialization and close outside of the loop works just fine:

Scanner in = new Scanner(System.in);
    //receive input integers from user
    do{

        System.out.println("?");
        input = in.nextInt();
        if(input != SENTINEL)
        numberList.add(input);

    }while(input != SENTINEL);
    in.close();

Why is it that the exception occurs when initializing the Scanner class in the loop? Thanks!

Exception is:

Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at main.Run.main(Run.java:25)
Dan Grover
  • 45
  • 6

1 Answers1

0

The reason that the first version crashes is that calling to Scanner.close - also closes the underlying stream: System.in.

It can be proved by wrapping System.in with a class that doesn't do anything in close() method (the code for UnClosableDecorator was taken from here):

public class Play {

    public static void main(String[] arg) throws IOException {

        int SENTINEL = 10;
        int input = 0;
        List<Integer> numberList = new ArrayList<>();

        System.setIn(new UnClosableDecorator(System.in));

        do {
            Scanner in = new Scanner(System.in);
            System.out.println("?");
            input = in.nextInt();
            System.out.println("[" + input + "]");
            in.close();
            if(input != SENTINEL) {
                numberList.add(input);
            }

        } while(input != SENTINEL);
        System.out.println("done");
    }
}


class UnClosableDecorator extends InputStream {

    private final InputStream inputStream;

    public UnClosableDecorator(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    @Override
    public int read() throws IOException {
        return inputStream.read();
    }

    @Override
    public int read(byte[] b) throws IOException {
        return inputStream.read(b);
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        return inputStream.read(b, off, len);
    }

    @Override
    public long skip(long n) throws IOException {
        return inputStream.skip(n);
    }

    @Override
    public int available() throws IOException {
        return inputStream.available();
    }

    @Override
    public synchronized void mark(int readlimit) {
        inputStream.mark(readlimit);
    }

    @Override
    public synchronized void reset() throws IOException {
        inputStream.reset();
    }

    @Override
    public boolean markSupported() {
        return inputStream.markSupported();
    }

    @Override
    public void close() throws IOException {
        //do nothing
    }
}
Community
  • 1
  • 1
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129