【问题标题】:Trying to read from the console in Java尝试从 Java 中的控制台读取
【发布时间】:2014-12-15 17:59:25
【问题描述】:

我刚刚开始使用 IntelliJ IDE 学习 Java。我懂一点 C#,所以逻辑是有道理的,但是到目前为止我无法克服一件事。

如何从控制台读取?在 C# 中,您可以使用 Console.ReadLine() 轻松读取人类输入的内容。在 Java 中,System.console().readLine(); 对我不起作用并抛出 NullPointerException

我在这里错过了什么?

【问题讨论】:

  • 查看Scanner 类,它应该会为您提供所需的内容。
  • 从您的问题标题中搜索最后一句话的第一个结果:“从控制台 JAVA 读取”给出:Java: How to get input from System.console()System.console().readLine(); 也适用于我(如果我通过控制台运行我的代码,在 IDE 之外)。我们需要查看您的代码并了解您如何使用它以及您遇到了什么异常。

标签: java intellij-idea


【解决方案1】:

注意:当我们通过java [options] [MainClass] 运行您的代码 控制台/终端时不会出现问题,因此如果这对您来说是有效的解决方案,您可以在此处停止阅读。此答案的其余部分适用于使用某些 IDE 运行其代码的人。

问题

大多数 IDE 使用 javaw.exe 而不是 java.exe 来运行 Java 代码(见下图)。

这两个程序之间的区别在于javaw 运行 Java 代码与当前终端/控制台无关(这对 GUI 应用程序很有用),并且因为没有关联的控制台窗口 System.console()返回null。因为System.console().readLine() 最终会变成null.readLine(),它会抛出NullPointerException,因为null 没有readLine() 方法(也没有任何方法/字段)。

但是仅仅因为没有关联的控制台,并不意味着我们不能与javaw进程通信。此进程仍然支持标准输入/输出/错误流,因此 IDE 进程(以及我们也通过它)可以通过System.inSystem.outSystem.err 使用它们。

这样 IDE 可以有一些选项卡/窗口并让它模拟控制台。

例如当我们在 Eclipse 中运行代码时:

package com.stackoverflow;

public class Demo {

    public static void main(String[] args) throws Exception {
        System.out.println("hello world");
        System.out.println(System.console());
    }

}

我们会看到结果

这表明尽管javaw.exe 没有关联的控制台(最后是null)IDE 能够处理来自javaw 进程System.out.println("hello world"); 的标准输出的数据并显示hello world

一般解决方案

让用户传递信息以处理使用标准输入流 (System.in)。但是由于in 很简单,InputStreamStreams 旨在处理 binary 数据,因此它没有可以轻松正确地将数据作为文本读取的方法(特别是如果编码可以参与)。这就是为什么将ReadersWriters ware 添加到Java 中的原因。

因此,为了让生活更轻松并让应用程序以文本形式从用户读取数据,您可以将此流包装在Readers 之一中,例如BufferedReader,这样您就可以使用readLine() 方法读取整行。不幸的是,这个类不接受Streams,而是Readers,所以我们需要某种适配器,它可以模拟阅读器并能够将字节转换为文本。但这就是 InputStreamReader 存在的原因。

所以让应用程序从输入流中读取数据的代码看起来像

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Hello. Please write your name: ");
String name = br.readLine();
System.out.println("Your name is: "+name);

首选/最简单的解决方案 - 扫描仪

为避免这种涉及将 Stream 转换为 Reader 的魔法,您可以使用 Scanner 类,该类旨在从 Streams 和 Reader 中以文本形式读取数据。

这意味着您可以简单地使用

Scanner scanner = new Scanner(System.in);
//...
String name = scanner.nextLine();

从用户那里读取数据(将由IDE使用标准输入流模拟的控制台发送)。

【讨论】:

  • 如果尝试使用Console.readPassword(),大多数IDE 不提供Console 的事实是一个杀手。 java.io.InputStreamjava.io.Readerjava.io.Consolejava.util.Scanner 都直接从 java.lang.Object 继承,并且没有共同的接口。
  • 有趣的是,java.exe 从命令行运行时提供 System.console()!=null,但从 Eclipse IDE 运行时提供 System.console()==null(已尝试使用 Oracle JDK9/JDK10 和 Eclipse Neon3)
  • 我收到此错误:java.util.NoSuchElementException: No line found。解决方案是运行主类而不是 gradle 任务
【解决方案2】:

您可以使用 Jframe。

JFrame frame = new JFrame("titile");

// prompt the user to enter their code
String code = JOptionPane.showInputDialog(frame, "promt here");

【讨论】:

  • 如何处理已经给出的输入?
【解决方案3】:

如果你真的需要控制台对象,你可以从命令行编译你的类。首先在我的 java 文件中,第一个语句是 package com.inputOutput;

进入您的项目“src”文件夹并像这样编译它:“javac com/inputOutput/Password.java”“com”和“inputOutput”是文件夹(包)。在src 文件夹中运行您的类文件
java com.inputOutput.Password"。它对我有用。

【讨论】:

    【解决方案4】:

    java.util.Scanner API 就是您要找的。​​p>

    【讨论】:

    • 关于为什么 Scanner 是 OP 应该使用的任何解释?像 BufferedReader 这样的其他替代品呢?如果使用得当,System.console() 也可以使用。
    • Scanner API 是一个非常简单的用于读取控制台输入的 API。很容易掌握它,尤其是对于初学者。要开始使用 BufferedReader API,用户应该了解不少与 java.io 相关的接口以及它们之间的确切区别。需要一些时间来掌握它并欣赏它。至少,这就是在 java-1.5 之前没有 Scanner API 时发生在我身上的事情
    • 这里还有另一个答案,用示例详细解释了扫描仪:stackoverflow.com/a/26473083/6693304
    猜你喜欢
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 2018-08-20
    • 1970-01-01
    • 2012-03-19
    • 2010-12-28
    相关资源
    最近更新 更多