关于System.in和System.out

本文介绍了Java中的基本IO操作,包括如何使用System.in进行键盘输入,以及System.out.println()的输出原理。通过理解输入流和输出流的概念,帮助读者掌握Java程序与用户交互的基本方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初次涉及IO是从键盘中输入,在控制面板上输出。

最简单的输入语法是:

Scanner input = new Scanner(System.in);

int x = input.nextInt();

最简单的输出语法是:

System.out.println();

在刚接触Java的时候根本不知道System.in是什么东西,也不明白为什么System.out.println()为什么会在控制面板上输出。

学完二进制输入输出后,一切开始明朗。

先说说System.in是什么。

查看API文档,在java.lang包中的方法System类中发现in是System中的由final修饰的InputStream类型的常量

in

public static final InputStream in
“标准”输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。

 

这说明System.in指的是一个输入流(InputStream),它的功能是创建一个由键盘输入的流

再说说System.in的工作原理。

众所周知,一个流必须要有一块地方提供该流的源头或者结尾,比如FileInputStream的构造方法:FileInputStream in = new FileInputStream(filesName)//filesName指的就是供该流读取字节的文件。大部分流都会有这样的一个文件。那System.in这个输入流的源头在哪里呢?System.in比较特殊,在使用这个流的时候,源头会更新,也就是说它的源头是新开辟出来的空间,用来储存键盘上输入的内容。

当我们调用System.in语句的时候实际上我们做了两个动作:1.创建了一个字节流;2.创建了一个类似于文件的储存空间(用完即被消除)。试分析下面语句:

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

while((s=in.readLine)!=null){

        //循环主体

}

这种从键盘上向一个流中输入数据的方法称为阻塞式方法,当你不在键盘上输入数据或者没有按enter键输入的时候,循环是不会进行的,流会暂停流动。

最后说说System.out.println().

这里的System.out不用我说大家也应该猜到,它也是一个流,翻看API文档:

out

public static final PrintStream out
“标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。

不过他是一个PrintStream类型的流,PrintStream类定义了println()方法,它的作用是想输出流的“尾巴”输出数据,而System.out的“尾巴”是可以设置的,设置语句为:System.setOut();//括号内是"尾巴",可以是一个文件,也可以是一个临时定义的容器类对象。

这两个东西其实不必深究,但是我总觉得有时间的话这些细节还是搞搞明白比较好,内心觉得踏实,我也是新手,希望各位大神不吝赐教,如果写得东西有误,希望各位大神不吝赐教。

 

### 如何重新开启 Java 程序中的标准输入流 `System.in` 在 Java 中,`System.in` 是一个静态字段,默认情况下指向 JVM 启动时的标准输入流。一旦关闭后无法直接通过简单的方式重开此输入流。然而可以通过自定义 InputStream 来实现类似的效果。 对于已经关闭的 `System.in` 流,在重启应用程序的情况下确实没有办法恢复默认行为。但是可以创建一个新的 InputStream 并将其设置给 `System.setIn()` 方法来替代原有的 `System.in`[^1]。 下面是一个简单的例子展示如何替换已关闭的标准输入: ```java import java.io.ByteArrayInputStream; import java.io.InputStream; public class ReopenStdin { public static void main(String[] args) throws Exception { // 原始输入操作... System.out.println("原始输入:"); int b = System.in.read(); while (b != -1 && b != '\n') { // 防止读取到换行符以外的数据 System.out.print((char)b); b = System.in.read(); } // 关闭原生输入流模拟问题场景 System.in.close(); try{ // 尝试再次读取会抛出异常 System.in.read(); }catch(Exception e){ System.out.println("\n\n尝试访问已关闭的输入流引发了异常"); } // 创建新的输入源并赋值给 System.in String newInputData = "这是新输入的内容"; InputStream fakeIn = new ByteArrayInputStream(newInputData.getBytes()); System.setIn(fakeIn); // 使用新的输入流继续工作 System.out.println("\n现在使用的是新的输入流:"); byte[] buffer = new byte[newInputData.length()]; System.in.read(buffer); System.out.println(new String(buffer)); } } ``` 需要注意的是,上述方法只是提供了一种绕过原有 `System.in` 被关闭情况下的解决方案,并是真正意义上的“重新打开”。如果可能的话,应该避免让程序逻辑导致 `System.in` 过早被关闭的情况发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值