Intellij Idea 尝试从Java控制台读取

nszi6y05  于 2023-03-17  发布在  Java
关注(0)|答案(5)|浏览(160)

我刚开始用IntelliJ IDE学习Java,我知道一点C#,所以逻辑上有点道理,但是有一件事到目前为止我还是不能克服。
如何从控制台读取?在C#中,使用Console.ReadLine()可以很容易地读取用户输入的内容。在Java中,System.console().readLine();不起作用,并抛出NullPointerException
我错过了什么?

6kkfgxo0

6kkfgxo01#

注意:当我们通过java [options] [MainClass]从控制台/终端运行代码时,问题不会出现,所以如果这对你来说是有效的解决方案,你可以停止阅读这里。这个答案的其余部分是为使用一些IDE运行代码的人准备的。

问题

大多数IDE使用javaw.exe而不是java.exe来运行Java代码(见下图)。
这两个程序的区别在于javaw运行Java代码 * 而不与当前终端/控制台关联 *(这对于GUI应用程序是有用的),并且由于没有关联的控制台窗口,System.console()返回null。因此,System.console().readLine()null.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

一般溶液

让用户使用标准输入流将信息传递给进程但是,由于in是简单的InputStreamStream,它们旨在处理 * 二进制 * 数据,因此,它不具有使其能够轻松且正确地将数据读取为文本的方法(特别是如果可能涉及编码的话)。这就是为什么ReadersWriters被添加到Java中。
因此,为了让应用程序更轻松地从用户那里读取文本数据,您可以将此流 Package 在Reader中,如BufferedReader,这将允许您使用readLine()方法读取整行。不幸的是,此类不接受Streams,但接受Reader。所以我们需要某种 * 适配器 * 来模拟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);

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

为了避免这种将Stream转换为Reader的“魔法”,您可以使用Scanner类,该类旨在将数据作为文本从Streams和Reader中读取。
这意味着您只需使用

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

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

hm2xizp9

hm2xizp92#

如果你真的需要控制台对象,你可以从命令行编译你的类。首先在我的java文件的第一个语句是package com.inputOutput;
进入你的项目“src“文件夹并编译它:“javac com/inputOutput/Password.java“”com“和”inputOutput“是文件夹(包)。请运行src文件夹中的类文件
java com.inputOutput.Password“。它对我很有效。

dnph8jn4

dnph8jn43#

您可以使用Jframe。

JFrame frame = new JFrame("titile");

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

hsgswve44#

通常情况下,Console对象需要操作系统提供一个有效的tty,但是IntelliJ IDEA输出窗口不提供。以独立于操作系统的方式完成这一点并不容易。不仅IntelliJ IDEA受到影响。您也不能在jshell中使用System.console()

|  Welcome to JShell -- Version 17.0.6
|  For an introduction type: /help intro

jshell> System.console()
$1 ==> null

jshell>

在Java 20中,这个问题已得到部分解决。现在,您可以添加VM选项-Djdk.console=jdk.internal.le。请转到“编辑运行/调试配置”,然后依次选择“修改选项”、“添加VM选项”并在此处键入该选项。之后,System.console()将在IDE中工作。它将挂接到IDE已拦截的System.in
请注意,此解决方案没有文档说明,也不受支持,因此可能无法在未来的Java版本中使用。您可以在此JDK issue中找到更多信息。

mitkmikd

mitkmikd5#

java.util.Scanner API就是你要找的。

相关问题