Scanner в Java NoSuchElementException
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
public static void main (String[] args){
boolean flag = true;
do {
System.out.println("Введите комманду(add|list|quit|change): ");
try(Scanner scanner = new Scanner(System.in)){
String com;
com = scanner.nextLine().toLowerCase().trim();
switch (com) {
case "add":
//тут добавление
break;
case "list":
//тут список
break;
case "quit":
flag = false;
break;
case "change":
//тут редактирование
break;
default:
System.out.println("Не верная комманда!");
scanner.close();
break;
}
}catch (Exception e){
System.out.println("Вы ввели не верную команду: " + e);
}
}while (flag);
}
}
При попадании в ветку default он больше не пытается считать новую строку из консоли и постоянно валится в ветку catch с ошибкой java.util.NoSuchElementException: No line found, хотя он не предлагает ввести новую строку. Подскажите как его заставить считать новую строку.
Ответы (1 шт):
Поместите do внутрь try-catch блока, а не наоборот. Сканнер закрывать не обязательно. Т.к. вы используете синтаксис "try-with-resource", сканнер сам закроется при выходе из блока.
Почему в коде вопроса проблема
Дело в том, что Scanner закрываясь, каскадно закрывает низлежащие стримы, в том числе и System.in. Поэтому, дальнейшие сканнеры, основанные на этом стриме будут вызывать ексепшены. Вот коороткое демо:
Это как бы наш сканер:
class ExampleClosable implements AutoCloseable{
@Override
public void close() throws Exception {
System.out.println("This instance closed.");
}
}
А это наш трай-кетч внутри цикла:
public class Main {
public static void main(String[] args) {
for(int i = 0; i < 2; i++){
try(ExampleClosable exampleClosable = new ExampleClosable()){
System.out.println("Loop body..");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Что приводит к выводу:
Loop body..
This instance closed.
Loop body..
This instance closed.
Т.е. при завершении первой итерации цикла, сканер закрывается, что приводит к закрытию System.in, что приводит к дальнейшим ексепшенам.