试图用Java从控制台读取

Lid*_*orA 39 java intellij-idea

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

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

我在这里错过了什么?

Psh*_*emo 64

问题

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

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

但仅仅因为没有相关的控制台,并不意味着我们无法与javaw流程进行通信.这个过程还支持标准输入/输出/错误流,所以IDE的过程(并通过它也是我们)可以通过使用它们System.in,System.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());
    }

}
Run Code Online (Sandbox Code Playgroud)

我们将看到结果

在此输入图像描述

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

一般解决方案

让用户将信息传递给进程使用标准输入流(System.in).但由于它in很简单InputStream并且Streams用于处理二进制数据,因此它没有方法可以让它轻松,正确地将数据作为文本读取(特别是如果可以涉及编码).这就是为什么ReadersWritersware添加到Java.

因此,为了使生活更轻松,让应用程序从用户读取数据作为文本,您可以将此流包装在其中一个Reader类似的内容中BufferedReader,这样您就可以使用readLine()方法读取整行.不幸的是这个类不接受Streams,但ReaderS,所以我们需要某种形式的适配器,将模拟Reader和能够字节转换为文本.但这就是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);
Run Code Online (Sandbox Code Playgroud)

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

为了避免将Stream转换为Reader的魔法,您可以使用Scannerclass,这意味着从Streams和Readers中读取数据作为文本.

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

Scanner scanner = new Scanner(System.in);
//...
String name = scanner.nextLine();
Run Code Online (Sandbox Code Playgroud)

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

  • 如果一个人试图使用`Console.readPassword()`,那么大多数IDE不提供`Console`这一事实都是一个杀手锏.`java.io.InputStream`,`java.io.Reader`,`java.io.Console`和`java.util.Scanner`都直接来自`java.lang.Object`并且没有共同的接口. (17认同)
  • 有趣的是,`java.exe`在从命令行运行时提供`System.console()!= null`,但提供从Eclipse IDE运行的`System.console()== null`(尝试使用Oracle JDK9/JDK10和Eclipse Neon3) (2认同)

Nag*_*dde -3

java.util.ScannerAPI 就是您正在寻找的。

  • 关于为什么 OP 应该使用扫描仪有什么解释吗?其他替代方案(例如 BufferedReader)怎么样?如果使用得当,“System.console()”也将起作用。 (4认同)