3

I have this simple code:

    public class Example {
       public Example() {
          Scanner scanner = new Scanner(System.in);
          int row = scanner.nextInt();   // exception at this line
          scanner.close();
       }

    public static void main(String[] args) {
        Example ex1 = new Example();   // this line successfully operate
        Example ex2 = new Example();   // exception : no such element exception at above line
    }
  }

I don't know why I always receive this Exception, when code run to ex2.

Toon Krijthe
  • 50,865
  • 37
  • 137
  • 200
hqt
  • 27,058
  • 46
  • 161
  • 235

2 Answers2

4

You Should add if(Scanner.hasNext()) before invoking scanner.nextInt(); You have the exception because no int found to be read.

  • 3
    It should be `hasNextInt()`. The `hasNextXXX()` should match the `nextXXX()`. But 1+ since your concept is correct. – Hovercraft Full Of Eels Oct 06 '12 at 12:03
  • in case that no such int to be read, what should to try next ? And why when I create another object, this error will appear ? (not appear at first time, i create ex1 but ex2). Thanks :) – hqt Oct 06 '12 at 12:19
  • 1
    What happen exactly is when you close the first scanner, you close also the stdin as described in the doc of scanner close method(http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html), for this reason the second will not works – James from CppDepend Team Oct 06 '12 at 12:31
  • it means : we shouldn't close scanner as my example above ? – hqt Oct 06 '12 at 12:47
  • 1
    the better way is to use one scanner instance and close it at the end of your main method.no need to have two scanners. – James from CppDepend Team Oct 06 '12 at 12:50
4

The problem is because you close the Scanner which in turn closes the underlying InputStream (in this case stdin). When you try to use stdin in again the Scanner is unable to retrieve any data because stdin has been closed.

If running directly from the commandlne then the correct way to provide access to stdin is to use the Console class. The console class provides a Reader wrapped around stdin that has a no-op close method. eg.

public class Example {
   public Example() {
      Scanner scanner = new Scanner(System.console().reader()); 
      // note change on above line
      int row = scanner.nextInt();
      scanner.close();
   }
}

Note, if you access stdin other than via the Console class then you'll likely cause problems for yourself. And if you invoke your java program other than directly from the command line then you will not get access to the console. For instance, the following will invokations cause problems.

echo 2 3 | java Example

or

Process p = new ProcessBuilder("java", "Example").start();
// write data to process
Dunes
  • 32,114
  • 7
  • 68
  • 83
  • Don't you mean System.in? (otherwise stdin must be general for input) – IMustBeSomeone Jun 09 '16 at 20:57
  • @IMustBeSomeone Stdin is a generic name for for an input stream that all programs get. In java, `System.in` is the specific object that represents stdin. – Dunes Jun 10 '16 at 07:11