Когда вы читаете System.in, вы читаете с клавиатуры по умолчанию, и это бесконечный поток ввода ... он имеет столько строк, сколько пользователь должен печатать. Я думаю, что отправка управляющей последовательности для EOF может работать, например, CTL-Z (или это CTL-D?).
Глядя на мою диаграмму AOL AOLII ... CTL-C ETX и CTL-D - EOT; любой из них должен работать, чтобы прервать текстовый поток. CTL-Z является SUB, который не должен работать (но он может, поскольку элементы управления исторически интерпретируются очень субъективно).
CTRL-D - это конец символьного или байтового потока для UNIX / Linux, а CTRL-Z - конец символьного или байтового потока для Windows (исторический артефакт с самых ранних дней Microsoft DOS).
С кодом вопроса, как написано, пустая строка не выйдет из цикла, потому что hasNextLine () не будет оценивать значение false. Он будет иметь терминатор линии во входном байтовом потоке.
System.in - это поток байтов со стандартного ввода, обычно консоль. Поэтому прекращение потока байтов останавливает цикл. Хотя nextLine () не блокирует ожидание ввода, hasNextLine () делает. Единственный способ, которым код заканчивается, в том виде, как он был разработан, - с CTRL-Z в Windows или CTRL-D в UNIX / Linux, который заканчивает поток байтов, вызывает hasNextLine (), чтобы не блокировать ожидание ввода и возвращать логическое значение false, которое завершается цикл while.
Если вы хотите, чтобы он завершился с пустым вводом строки, вы можете проверить непустые строки как часть условия продолжения цикла. Следующий код демонстрирует, как изменить базовый дизайн вопроса, который использует hasNextLine () и nextLine () для того, который завершает работу, если он получает пустую строку или конец входного символа (т.е. CTRL-Z в Windows или CTRL-D в UNIX / Linux). Дополнительный код в условии while использует функцию операторов присваивания, в которой они могут быть оценены как выражение для возврата назначенного значения. Поскольку это объект String, метод String.equals () может использоваться с оценкой.
Другой дополнительный код просто добавляет некоторый отпечаток, чтобы сделать то, что происходит очевидным.
// HasNextLineEndDemo.java
import java.util.*;
public class HasNextLineEndDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// this code is a bit gee-whiz
// the assignment expression gets assigned sc.nextLine()
// only if there is one because of the &&
// if hasNextLine() is false, everything after the &&
// gets ignored
// in addition, the assignment operator itself, if
// executed, returns, just like a method return,
// whatever was assigned to str which,
// as a String object, can be tested to see if it is empty
// using the String.equals() method
int i = 1; // input line counter
String str = " "; // have to seed this to other than ""
System.out.printf("Input line %d: ", i); // prompt user
while (sc.hasNextLine() && !(str = sc.nextLine()).equals("")) {
System.out.printf("Line %d: ", i);
System.out.println("'" + str + "'");
System.out.printf("Input line %d: ", ++i);
} // end while
System.out.println("\nYOU'VE GOT THROUGH");
} // end main
} // end class HasNextLineEndDemo
Нажмите Ctrl + D, чтобы завершить ввод из stdin. (Windows: Ctrl + Z) или введите ввод из команды:
echo -e "abc\ndef" | java Program