Java User Input
›Short versionOpen if you only have a minute.
- Scanner reads text from System.in, a file, or another Readable. It blocks while it waits for the next token.
- next() and nextInt() take one whitespace-delimited token. They leave the rest of the line, including the newline, in the scanner.
- nextLine() takes the rest of the current line. Right after nextInt(), that rest is often empty.
- hasNextInt() checks the next token before you parse it. A false result means you should consume the bad token and ask again.
- Do not close a Scanner wrapped around System.in unless you mean to close standard input for the process.
- For a line-oriented prompt, read lines with nextLine() and parse those strings. The token methods and the line method then stop surprising each other.
The program asks for an age, then a name. The person types 30, presses Enter, and the name comes back blank. The age was read. The Enter key was left sitting in the , and the next read treated that leftover break as the whole name.
A scanner on the keyboard
is System.in. The scanner wraps it and parses text. Import java.util.Scanner.
import java.util.Scanner;
public class Prompt {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Name: ");
String name = scanner.nextLine();
System.out.println("Hello, " + name);
}
}$ javac Prompt.java$ java Prompt
nextLine waits until the person presses Enter, then returns the characters before that break. This program uses one line method, so there is no leftover token to trip over. The scanner is not closed. Closing it would close .
A token is not a line
A is split on the , which is whitespace unless you change it. nextInt() consumes the digits and stops. The newline the Enter key produced is still buffered.
System.out.print("Age: ");
int age = scanner.nextInt();
System.out.print("Name: ");
String name = scanner.nextLine(); // often ""That call finishes the age's line. It returns the empty remainder. The name the person types is still waiting, and the program has already moved on. One fix is to call nextLine() once to discard the remainder, then again to read the name. The cleaner fix for a prompt is to read both answers as lines and parse the age from its string.
System.out.print("Age: ");
int age = Integer.parseInt(scanner.nextLine().trim());
System.out.print("Name: ");
String name = scanner.nextLine();parseInt throws NumberFormatException on a blank or a word. Catch it and ask again if a person is at the keyboard. is the check you use when you stay with token methods: it peeks without throwing, and you still have to consume a token that failed the check or the same word will fail forever.
while (!scanner.hasNextInt()) {
scanner.next(); // drop the word that is not an int
System.out.print("Enter a whole number: ");
}
int age = scanner.nextInt();A scanner on a file should be closed, because it holds the file open. Try-with-resources does that when the block ends. Use it for new Scanner(path). Keep a System.in scanner out of that pattern unless the block is the whole program and nothing will read the keyboard afterward.
try (Scanner file = new Scanner(Path.of("notes.txt"))) {
while (file.hasNextLine()) {
System.out.println(file.nextLine());
}
}nextInt() just read 30 from the line 30 followed by Enter. What does the next nextLine() return?
An empty string. nextInt() consumed 30 and left the newline. nextLine() reads through that newline and finds no other characters. Read the age with nextLine() and Integer.parseInt, or call nextLine() an extra time to discard the leftover break before the real name line.