1

To get around the skipping nextLine() issue, and to make the code cleaner, have I a couple of times used the following approach:

private String getInput() {
    return new Scanner(System.in).nextLine();
}

This have not been any production code, just small projects, so I haven't cared much if this could give performance issues since I found the approach very convenient. I really like to use this method for all inputs and parse the return value.

To the question - is this a very bad practice? I does not feel good to not close the Scanner, but since the object gets out of reach, have I been thinking that the Scanner object should be garbage collected and therefore also closed. How does the gc handle this?

Community
  • 1
  • 1
Tobias Johansson
  • 368
  • 3
  • 11

2 Answers2

1

You must not close it in this case otherwise System.in will be closed too such that you won't be able to get any new input, indeed if you execute this simple code:

Scanner scanner = new Scanner(System.in);
scanner.close();
scanner = new Scanner(System.in);
scanner.nextLine(); // -> Exception here

You will get the next exception:

Exception in thread "main" java.util.NoSuchElementException: No line found
    at java.util.Scanner.nextLine(Scanner.java:1540)
    at hello.Application.main(Application.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)

The only real issue that I see with your approach is the fact that it can be inefficient if you call this method regularly as you create a new Scanner instance at each call, moreover it could be JDK implementation specific because if you have one implementation of Scanner that implements the method finalize it may close the Scanner which would lead to the error described above.

Nicolas Filotto
  • 39,066
  • 11
  • 82
  • 105
  • Could you explain the error above more thoroughly, I don't get the issue? And of course I understand its inefficient, but the performance affect must be _minimal_. – Tobias Johansson Jun 02 '16 at 19:26
  • 1
    Check the method close of a Scanner, if you close a scanner it closes the source too which is System.in here, so you can't read the input stream anymore – Nicolas Filotto Jun 02 '16 at 19:26
  • if you do it a couple of times indeed the affect should be minimal, it depends on your use case – Nicolas Filotto Jun 02 '16 at 19:32
  • Great I see now, good explanation, tested your example too, it give me that error. Anyhow, I could not produce this error with my approach. Now I'm curious why this getInput() method don't cause any error. – Tobias Johansson Jun 02 '16 at 19:37
  • simply because the scanner is never closed, it is simply garbage collected – Nicolas Filotto Jun 02 '16 at 20:52
-1

The Scanner has a finalize() method which will close any native resources when the object is GC'd.

Kayaman
  • 67,952
  • 3
  • 69
  • 110