The biggest problem with your approach is that if nextInt()
fails because the user did not enter a valid integer, the scanner does not advance. The scanner has a pointer that points to the next character to read from the input. When you use nextInt()
, if the next "token" is an integer, the scanner will advance the pointer past the integer. But if it isn't an integer, an exception is thrown--and the pointer stays in the same place as before. So when you catch the exception, then call nextInt()
, the scanner tries to read the same invalid integer that it just tried to read last time.
To skip over the bad integer, you can say input.next()
to skip over one token, or input.nextLine()
to skip over the entire remainder of the input line, before trying to read another integer. (Both of these return String
results, but you can discard the result since it's not important to you).
However, this is not really a good way to use try/catch
. If the user is having a bad day and enters another invalid integer, the scanner will throw an exception, and it will not be caught, since you are not in the try
when the second exception is thrown. catch
doesn't loop back and catch it again. The best idiom for this is a loop:
boolean validIntegerEntered = false;
System.out.println("ENTER A NUMBER: ");
while (!validIntegerEntered) {
try {
n=input.nextInt();
validIntegerEntered = true; // will not get here if nextInt()
// throws an exception
}
catch (InputMismatchException e) {
input.nextLine(); // let the scanner skip over the bad input
System.out.println("ERROR!!! \nENTER A NUMBER :");
// don't call nextInt() here; loop back, and nextInt() will be called
// in the try statement
}
}