Когда вы вводите токен, который не является числом, вызов nextInt не перемещает сканер за пределы токена.В результате он просто читает один и тот же токен снова и снова.
Вот документация для nextInt: http://download.oracle.com/javase/6/docs/api/java/util/Scanner.html#nextInt%28%29 (хотя соответствующее поведение фактически описано в версии, которая принимает аргумент, здесь:http://download.oracle.com/javase/6/docs/api/java/util/Scanner.html#nextInt%28int%29)
Итак, чтобы дать вам быстрый пример, давайте предположим, что входная строка равна "1 2 Foo"
.Я добавлю X, чтобы показать, где сейчас находится сканер.Это начинается "X1 2 Foo"
.Затем происходит первый вызов input.nextInt()
.Возвращает 1, и теперь мы находимся на "1 X2 Foo"
.Затем происходит второй вызов input.nextInt()
.Возвращает 2 и теперь мы находимся на "1 2 XFoo"
.Затем происходит третий вызов input.nextInt()
.Он не возвращается, а создает исключение InputMismatchException, а также не продвигает сканер.Итак, мы все еще на "1 2 XFoo"
.Поэтому, когда мы называем это в четвертый или пятый раз, происходит то же самое.
Чтобы решить эту проблему, вызов input.next()
будет потреблять следующий токен, каким бы он ни был.После этого вызова, в нашем примере, мы будем на "1 2 FooX"
.
Обратите внимание, однако, что вызов input.next()
также может генерировать исключения.В частности, он может генерировать исключение IllegalStateException, если сканер закрыт (что не должно происходить в вашем коде), или исключение NoSuchElementException, если сканер достиг конца ввода (что не произойдет, если вы читаете с клавиатуры, как яПредположим, что вы).Но чтобы быть в безопасности, вы должны либо перехватить эти ошибки и выйти из цикла, либо не перехватить их и вместо этого объявить их как выброшенные вашим методом.