试图用Java从控制台读取数据

试图用Java从控制台读取数据,java,intellij-idea,Java,Intellij Idea,我刚刚开始用IntelliJ IDE学习Java。我知道一点C#所以逻辑是有道理的,但是有一件事我至今无法克服 如何从控制台读取?在C#中,您可以使用Console.ReadLine()轻松读取用户输入的内容。在Java中,System.console().readLine()不适用于我,并引发NullPointerException 我在这里遗漏了什么?java.util.ScannerAPI是您正在寻找的。注意:当我们通过java[options][MainClass]从控制台/终端运行代码

我刚刚开始用IntelliJ IDE学习Java。我知道一点C#所以逻辑是有道理的,但是有一件事我至今无法克服

如何从控制台读取?在C#中,您可以使用
Console.ReadLine()
轻松读取用户输入的内容。在Java中,
System.console().readLine()不适用于我,并引发
NullPointerException


我在这里遗漏了什么?

java.util.Scanner
API是您正在寻找的。注意:当我们通过
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
进程通信。这个进程仍然支持标准的输入/输出/错误流,因此IDEs进程(我们也可以通过它)可以通过
System.in
System.out
System.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”)标准输出的数据并显示
你好世界

通解 要让用户将信息传递给进程,请使用标准输入流(
System.in
)。但由于
中的
很简单,
InputStream
Stream
用于处理二进制数据,因此它没有能够让它轻松、正确地将数据读取为文本的方法(特别是在可能涉及编码的情况下)。这就是为什么
读卡器
写卡器
被添加到Java中的原因

因此,为了简化操作并让应用程序以文本的形式从用户处读取数据,您可以将此流封装在一个
读取器
中,如
BufferedReader
,它将允许您使用
readLine()
方法读取整行数据。不幸的是,这个类不接受
,而是
读卡器
s,因此我们需要某种适配器来模拟读卡器,并能够将字节转换为文本。但这就是
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);
首选/最简单的解决方案-扫描仪 为了避免将流转换为读卡器的魔法,您可以使用
Scanner
类,该类用于从流和读卡器中以文本形式读取数据

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

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

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

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

进入你的项目“
src
”文件夹,像这样编译:“
javac com/inputOutput/Password.java
”“
com
”和“
inputOutput
”是文件夹(包)。在
src
文件夹中运行类文件

java com.inputOutput.Password
”。它对我来说很有效。

你可以使用Jframe。

JFrame frame = new JFrame("titile");

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

查看
Scanner
类,它应该会提供您需要的信息。通过谷歌搜索问题标题最后一句话的第一个结果:“从控制台读取JAVA”给出:。另外
System.console().readLine();
对我来说很好(如果我在IDE之外通过控制台运行代码)。我们需要查看您的代码,了解您是如何使用它的,以及您遇到了什么异常。有关为什么扫描仪是OP应该使用的东西的任何解释都可能重复?其他替代方法如BufferedReader如何?还有
System.console()
如果使用得当也可以使用。Scanner API是一个非常简单的API,用于读取控制台输入。掌握它非常容易,特别是对于初学者。要开始使用BufferedReader API,用户应该了解相当多与java.io相关的接口以及它们之间的确切差异。掌握它需要一些时间至少,这就是我在java-1.5之前没有Scanner API时所遇到的情况。这里有另一个答案,用示例详细解释了Scanner:如果一个人试图使用
Console.readPassword()
,大多数IDE不提供
控制台的事实是一个杀手。
java.io.InputStream
java.io.Reader
java.io.Console
java.util.Scanner
都是直接从
java.lang.Object
派生出来的,没有共同的接口。有趣的是,
java.exe
提供了e> 当从命令行运行时,System.console()!=null
,但提供了从Eclipse IDE运行时的
System.console()==null
whan(使用Oracle JDK9/JDK10和Eclipse Neon3进行了尝试)我遇到了这个错误:
java.util.NoSuchElementException:找不到行
。解决方案是在主类而不是gradle任务中运行的。如何处理已给出的输入