为什么System.console()为命令行应用程序返回null?

时间:2014-01-07 21:49:54

标签: java console console-application system-calls

我正在开发一个依赖于用户命令行输入的遗留应用程序:

String key = System.console().readLine("Please enter the license key: ");

但是,我收到了NullPointerException,因为System.console()给了我一个空的。

为什么System.console()为命令行应用返回null?当它从终端以及IDE运行时会发生。

2 个答案:

答案 0 :(得分:2)

如果你从终端窗口启动java,那么它确实应该工作,即使我还没有尝试过OSX。

如果直接从终端使用java运行简单测试,它是否有效?

echo 'public class Test { public static void main(String[] args) {System.console().printf("hello world%n");}}' >Test.java && javac Test.java && java Test 

预期产出:

hello world

如果它不起作用,那么抱歉,您的平台上没有控制台支持。

但是,如果它有效,并且您的程序没有,那么程序的启动方式就会出现问题。

检查java二进制文件是如何启动的?它是从shell脚本开始的吗?检查stdin / stdout是否未被重定向或管道输入某些东西,也可能是它没有在后台启动。

例如:这可能会使System.console()返回null。

java Test | tee >app.log    

和此:

java Test >/tmp/test.log

这似乎适用于我的机器(linux)

java Test &

即使在几个gc和终结器之后,似乎System.setOutSystem.setErrSystem.setIn也不会影响控制台。


然而:

结束(原始)System.outSystem.in也会停用console

echo 'public class Test { public static void main(String[] args) {System.out.close();System.console().printf("hello world%n");}}' >Test.java && javac Test.java && java Test 

预期产出:

Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:1)

因此;扫描代码以查找关闭流的地方,或者将System.out传递给可能关闭的地方。

答案 1 :(得分:0)

要从标准输入(命令行输入)读取,您必须使用某种流读取器来读取System.in流。 由

初始化的InputStreamReader
    InputStreamReader(System.in) 

让您逐个字符地阅读。 但是,我建议用BufferedReader包装它:

    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String inputLine = reader.readLine();

必须导入

    java.io.*;