#java #while-loop #java.util.scanner #pmd #nosuchelementexception
Вопрос:
Я немного новичок в программировании и очень новичок в gradle и pmd-плагине, так что, пожалуйста, смилуйтесь.
Если пользователь вводит число, scanner.nextLine() будет выдавать исключение NoSuchElementException на каждой итерации, создавая бесконечный цикл.
public class Console {
public int readInteger(String line) {
Integer x = null;
while(x == null) {
try(Scanner scanner = new Scanner(System.in) {
System.out.print(line);
x = scanner.nextInt();
} catch(InputMismatchException exc) {
//error message
} catch(InvalidStateException exc) {
//error message
} catch(NoSuchElementException exc) {
//error message
}
}
return x;
}
}
Я буду признателен за каждую руку помощи.
Редактировать: Понял, что моя проблема возникает в сочетании с методом Scanner.nextLine (). Порядок не имеет значения, мой цикл по-прежнему является бесконечным циклом с тем же исключением NoSuchElementException.
Комментарии:
1. Какой ввод вы вводите?
Ответ №1:
Просто измените
x = scanner.nextLine();
Для
x = scanner.nextInt();
Также нет, он не войдет в бесконечный цикл, потому что вы используете неправильный метод, он просто не будет работать .
Комментарии:
1. scanner.nextLine() был ошибкой, не скопировал код, просто запомнил его и записал в вопрос. исправлено, но проблема все еще остается
Ответ №2:
Вот полный (компилируемый) пример:
import java.util.Scanner;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;
public class Console {
public int readInteger(String line) {
Integer x = null;
while(x == null) {
try(Scanner scanner = new Scanner(System.in)) {
System.out.print(line);
x = scanner.nextInt();
} catch(InputMismatchException exc) {
//error message
} catch(IllegalStateException exc) {
//error message
} catch(NoSuchElementException exc) {
//error message
}
}
return x;
}
public static void main(String[] args) {
Console c = new Console();
int age = c.readInteger("How old are you? ");
System.out.printf("You are %d years old.%n", age);
}
}
Примечание: Исключение InvalidStateException не существует, это исключение IllegalStateException.
Сохраните этот фрагмент кода Console.java
и запустите его с помощью java 11 , например java Console.java
.
Если вы входите, например. 42
это работает. «Бесконечный цикл» начинается, если вы не введете целое число, например very old
. Теперь нам нужно на самом деле обработать исключения. В таком случае InputMismatchException
будут выброшены. Но неверный ввод не используется и все еще находится в сканере — поэтому повторная попытка с nextInt()
вызовет то же исключение снова. Нам придется сначала прочитать неверный токен, прежде чем пользователь сможет ввести новые данные. Мы можем считывать данные с nextLine()
помощью , но поэтому нам нужен доступ к сканеру, поэтому нам нужно открыть экземпляр сканера раньше — и выполнить цикл и обработку ошибок внутри внешней попытки с ресурсами.
Если пользователь закроет входной поток (с Ctlr Z
под Windows или Cltr D
под Linux), то NoSuchElementException
будет выброшен, поэтому нам также нужно будет обработать этот случай. IllegalStateException
будет выброшено, если сам экземпляр сканера закрыт.
Вот фиксированный полный пример:
import java.util.Scanner;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;
public class Console {
public int readInteger(String line) {
Integer x = null;
try (Scanner scanner = new Scanner(System.in)) {
while(x == null) {
try {
System.out.print(line);
x = scanner.nextInt();
} catch(InputMismatchException exc) {
String wrongInput = scanner.nextLine();
System.out.printf("The input '%s' is not a number. Please try again.%n", wrongInput);
} catch(NoSuchElementException exc) {
// no input provided
System.exit(1);
}
}
}
return x;
}
public static void main(String[] args) {
Console c = new Console();
int age = c.readInteger("How old are you? ");
System.out.printf("You are %d years old.%n", age);
}
}