尝试从Java中的控制台读取
我刚开始用IntelliJ IDE学习Java。 我知道有点C#所以逻辑是有道理的,但是到目前为止我还是无法克服它。
我如何从控制台读取? 在C#中,可以使用Console.ReadLine()
轻松读取人类input的内容。 在Java中, System.console().readLine();
不适用于我,并引发NullPointerException
。
我在这里错过了什么?
问题
大多数IDE使用javaw.exe
而不是java.exe
来运行Java代码。
这两个程序之间的区别在于, javaw
运行Java代码而不与当前的terminal/控制台 (这对于GUI应用程序是有用的)关联,并且由于没有关联的控制台窗口System.console()
返回null
。 由于System.console().readLine()
与null.readLine()
相同,因为null
没有readLine()
方法(也没有任何方法/字段),所以抛出NullPointerException
。
但是因为没有控制台,这并不意味着我们不能和javaw
进程通信。 这个过程支持input,输出和错误stream,所以IDE(和我们)可以使用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
被用来运行这个代码,所以没有真正的控制台关联,但是它被名为Console的标签模拟。
解
为了让用户传递信息进行处理,可以使用标准inputstream(存储在System.in
)。 但是由于in
是简单的InputStream
和Stream
是为了处理二进制数据,所以它没有方法让它很容易以文本的forms读取数据(特别是在涉及编码的情况下)。 这就是为什么Readers
和Writers
洁具添加到Java。
所以为了让生活更轻松,让应用程序以文本forms读取用户的数据,可以将这个stream封装到BufferedReader
之类的Reader
,这样可以使用readLine()
方法读取整行。 不幸的是,这个类不接受Streams
而是Reader
,所以我们需要一些适配器来模拟Reader,并且能够将字节转换成文本。 但是这就是InputStreamReader
存在的原因。
因此,让应用程序从inputstream中读取数据的代码可能看起来像
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Hello. Write your name: "); String name = br.readLine(); System.out.println("Your name is: "+name);
其他(更简单,可能是首选)解决scheme
为了避免涉及将Stream转换为Reader的这种魔法 ,您可以简单地使用Scanner
类,这是为了从Streams和Readers中以文本的forms读取数据。
这意味着你可以简单地使用
Scanner scanner = new Scanner(System.in); //... String name = scanner.nextLine();
从用户读取数据(将由IDE使用标准inputstream模拟的控制台发送)。
java.util.Scanner
API是你正在寻找的。