Skip to content

How to fix: Java input mismatch

In Java, the java.util.InputMismatchException is a runtime exception thrown by the Scanner class. It occurs when the token retrieved by a scanner does not match the pattern for the expected type, or the token is out of range for the expected type.

Technically, when you call a method like scanner.nextInt(), the scanner attempts to interpret the next sequence of characters as an integer based on the current Locale. If the characters are non-numeric (e.g., “abc”) or represent a floating-point number (e.g., “10.5”), the scanner throws this exception. Crucially, the scanner does not advance past the mismatched token, which often leads to infinite loops if not handled correctly.

Cause Description Technical Trigger
Type Incompatibility Providing a String or Boolean when a numeric type is expected. nextInt() encountering [a-zA-Z] characters.
Locale Mismatch Using a period . instead of a comma , (or vice versa) for decimals. nextDouble() failing due to Locale settings.
Out of Range Providing a value larger than the data type can hold. Inputting 2^32 into nextInt().
Radix Mismatch Inputting a value that doesn’t match the expected base. Inputting 9 when scanner.useRadix(8) is set.

1. Defensive Programming with hasNext Validation

Section titled “1. Defensive Programming with hasNext Validation”

The most robust way to prevent this exception is to peek at the buffer before consuming the token.

Scanner scanner = new Scanner(System.in);
System.out.print("Enter an integer: ");
if (scanner.hasNextInt()) {
int value = scanner.nextInt();
System.out.println("Received: " + value);
} else {
String invalid = scanner.next(); // Consume the invalid token to clear the buffer
System.err.println("Error: '" + invalid + "' is not a valid integer.");
}

To avoid the common “trailing newline” bug and handle input more gracefully, read the entire line as a String and parse it manually.

Scanner scanner = new Scanner(System.in);
System.out.print("Enter a double: ");
String input = scanner.nextLine();
try {
double value = Double.parseDouble(input);
System.out.println("Parsed: " + value);
} catch (NumberFormatException e) {
System.err.println("Invalid numeric format: " + input);
}

3. Handling Exceptions and Clearing the Buffer

Section titled “3. Handling Exceptions and Clearing the Buffer”

If you use a try-catch block, you must explicitly call scanner.next() or scanner.nextLine() in the catch block. Otherwise, the invalid token remains in the buffer, causing an infinite loop in a menu-driven program.

Scanner scanner = new Scanner(System.in);
int choice = 0;
while (true) {
try {
System.out.print("Select an option (1-5): ");
choice = scanner.nextInt();
break; // Exit loop on successful input
} catch (InputMismatchException e) {
System.out.println("Invalid input. Please enter digits only.");
scanner.next(); // CRITICAL: Clear the bad token from the buffer
}
}
  • Normalize Locale: Use scanner.useLocale(Locale.US); to ensure that decimal points are always represented by a dot . regardless of the user’s system region.
  • Buffer Management: Always follow a nextInt() or nextDouble() with a nextLine() if you plan to read a String immediately after. This consumes the leftover newline Enter character.
  • Preference for nextLine(): In high-integrity applications, prefer reading all input as String via nextLine() and using wrapper classes (e.g., Integer.parseInt()) for conversion. This provides more control over the parsing logic and state of the input stream.
  • Scanner Closing: Only close the Scanner if it isn’t wrapping System.in. Closing a scanner attached to standard input also closes the underlying stream, which cannot be reopened during the JVM’s lifecycle.