HOWTO · Java

Java 等待输入

本教程演示如何让 java 等待用户输入

本页内容

Java 程序从 System.in 读取控制台输入时,会等待用户输入。读取操作会阻塞程序,直到有一行输入到达;随后程序继续处理该行。此时编译已经完成,并未暂停。需要读取单词或整行时,可以使用 Scanner;需要按行读取字符时,可以使用 BufferedReader;图形界面应用则可以使用 JOptionPane。

使用 Scanner 类的 nextLine() 方法等待用户输入

Scanner.nextLine() 会读取当前行剩余的内容,并将其作为 String 返回。如果标准输入仍处于打开状态,但暂时没有可读取的行,此调用会等待输入。下面的完整程序会先检查是否有可读取的行,因此即使输入已经结束,也能正常退出:

运行此示例:

import java.util.Scanner;

public class ScannerExample {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.print("Enter a line: ");
    if (scanner.hasNextLine()) {
      String line = scanner.nextLine();
      System.out.println("You entered: " + line);
    } else {
      System.out.println("No input was provided.");
    }
  }
}

示例输入:Ada。如果只看程序写入标准输出(stdout)的内容,对应文本是 Enter a line: You entered: Ada:print() 输出提示文字但不添加换行符,println() 则在同一行的标准输出中追加响应。这个连在一起的文本描述的是程序输出,不包含终端对键盘输入的回显。在会回显输入的交互式终端中,通常会先显示 Enter a line: Ada,然后在下一行显示 You entered: Ada。按下 Enter 提交输入后,终端会回显输入并换到下一行,接着 println() 才输出响应。随后,nextLine() 会返回提交的那一行,程序继续执行。

如果输入流在下一行可用之前到达末尾,hasNextLine() 会返回 false。在这种情况下若未先检查就调用 nextLine(),会抛出 NoSuchElementException;如果 Scanner 已关闭后再调用,则会抛出 IllegalStateException。如果应用的其他部分还需要使用 System.in,请避免关闭包装该输入流的扫描器,因为关闭扫描器也会关闭其输入源。

使用 BufferedReader 等待用户输入

BufferedReader.readLine() 也会等待从 System.in 读取一行,并将该行作为 String 返回。如果输入流在下一行到达前结束,它会返回 null。读取时可能会报告 IOException,因此应在调用代码中处理这种情况:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BufferedReaderExample {
  public static void main(String[] args) {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    System.out.print("Enter your name: ");
    try {
      String name = reader.readLine();
      if (name == null) {
        System.out.println("No input was provided.");
      } else {
        System.out.println("Hello, " + name + "!");
      }
    } catch (IOException e) {
      System.out.println("Could not read input: " + e.getMessage());
    }
  }
}

示例输入:Ada。对应的程序输出是 Enter your name: Hello, Ada!;终端可能会在提示文字后回显输入的姓名。按下 Enter 提交这一行后,readLine() 会返回该行,程序随后继续执行 else 分支。如果输入流已经结束,方法则会返回 null,程序因此输出无输入时的提示消息。

如果代码以读取完整行为主,或已经使用 java.io API,可以选择 BufferedReader。这两种控制台输入方式都会在等待期间阻塞正在运行的线程;它们都不会暂停编译。

在 GUI 应用中使用 JOptionPane 等待用户输入

在桌面 GUI 中,JOptionPane.showInputDialog("Enter your name:") 会打开一个对话框,并将用户输入的文本作为 String 返回。使用返回值前应先检查:如果用户选择 Cancel 或关闭对话框,该方法会返回 null。可以通过类似 if (userInput == null) { /* handle cancellation */ } 的分支处理这种情况;否则就处理输入的文本。这种 Swing 交互需要图形桌面环境,因此这里不将其作为控制台程序演示。

总结

需要简单的控制台提示时,可使用 Scanner.nextLine();需要按行读取并显式处理 I/O 时,可使用 BufferedReader.readLine();需要 GUI 对话框时,可使用 JOptionPane.showInputDialog。每种情况下,输入返回后程序都会继续执行;使用控制台输入时要考虑输入流结束的情况,使用对话框时则要处理取消操作返回的 null。