Интересная проблема!
Что происходит, так это то, что сканер пытается преобразовать нецелое число в целое и понимает, что не может, поэтому выдает исключение InputMismatchException. Однако он продвигается дальше маркера только в том случае, если перевод был успешным.
Это означает, что недопустимая строка все еще находится во входном буфере, и она будет терпеть неудачу при переводе каждый раз, когда вы зацикливаетесь и пытаетесь вызвать nextInt()
. Вы никогда не устанавливаете dataType
в true, и поэтому вы зацикливаетесь бесконечно.
Чтобы увидеть это в действии, вы можете взять произвольное содержимое в блоке catch и распечатать его:
catch(Exception JavaInputMismatch){
System.out.println( sc.next() );
System.out.println("Option not available.Try again.");
}
Действительно, после неверного ввода мы получаем следующее:
Enter a number: hello
hello
Option not available.Try again.
Enter a number:
И мы не зацикливаемся бесконечно. Это связано с тем, что вызов next()
захватил значение из входного буфера и переместил указатель сканера в этот буфер к следующему слоту, который сейчас пуст. Так что nextInt()
будет ждать ввода в этом случае.
О, и причина, по которой он отлично работает, если вы инициализируете в цикле, заключается в том, что сканер всегда начинает считывать ввод заново; сканеры не разделяют состояние между экземплярами, поэтому «привет», который был в буфере для предыдущей итерации, отсутствует в буфере для следующей из-за повторной инициализации.
Технически он все еще находится в стандартном входном буфере, но указатель сканера на этот буфер находится за пределами недопустимой строки, поскольку он начнет считывать любой новый ввод, а не существующий ввод.
person
Purag
schedule
11.06.2015
Scanner sc = new Scanner(System.in);
перед циклом? - person Purag   schedule 11.06.2015while(dataType==false)
является технически правильным синтаксисом, считается более элегантным выразить его какwhile(!dataType)
. Кроме того, вы можете использовать циклdo-while
для случаев, когда вы хотите принудительно выполнить хотя бы одну итерацию. - person hfontanez   schedule 11.06.2015== false
. Это намного понятнее, и если вы правильно назовете свои переменные (например, вместо dataType, если бы он был intEntered), это будет читаться как настоящий английский. - person Purag   schedule 11.06.2015==
. - person hfontanez   schedule 11.06.2015