热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

调用scanner.close()报错Java.io.Exception:Streamclosed;的原因分析

引言:想对比用于控制台输入的Scanner和BufferedReader,因此放在同一个方法中,之前学习或者使用时没有特别注意过要不要在使

引言:想对比用于控制台输入的Scanner和BufferedReader,因此放在同一个方法中,之前学习或者使用时没有特别注意过要不要在使用完后关闭Scanner,最初根据Eclipse的提示,在使用完Scanner后调用了close(),可是当我再次运行的时候,直接影响到后面InputStreamReader,然后分析原因:从第19行开始,后面的代码都没有用到Scanner,理论上没问题的,然后再看了看,Scanner中有用到System.in,InputStreamReader中也有用到System.in,出问题应该就在System.in了。

 

package com.temp;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;public class Test {public static void main(String[] args) throws Exception{// TODO Auto-generated method stubScanner scanner = new Scanner(System.in);System.out.println("please input a Integer number");int number = scanner.nextInt();System.out.println("your input is " + number);// scanner.close();InputStreamReader inputstreamreader = new InputStreamReader(System.in);BufferedReader bufferReader = new BufferedReader(inputstreamreader);System.out.println("please input your info");String string = bufferReader.readLine();System.out.println("your information is " + string);}}

在我们写代码的时候,如果申明后用完Scanner后没有及时关闭,IDE会自动提示我们需要关闭流

(Eclipse IDE会有提示,Intellij IDEA没有提示)

如果我们没有手动关闭,虽然Scanner对象最终会进入被回收的队列中,但不是立刻回收,这会造成内存占据。

为了节省内存我们一般在使用完Scanner后会调用scanner.close();来关闭输入流。

下面开始分析:

1、查看close()方法的源码

/*** Closes this scanner.**

If this scanner has not yet been closed then if its underlying* {@linkplain java.lang.Readable readable} also implements the {@link* java.io.Closeable} interface then the readable's close method* will be invoked. If this scanner is already closed then invoking this* method will have no effect.**

Attempting to perform search operations after a scanner has* been closed will result in an {@link IllegalStateException}.**/private boolean closed = false; // Boolean indicating if this scanner has been closedprivate Readable source; // The input sourcepublic void close() {if (closed)return;if (source instanceof Closeable) {try {((Closeable)source).close();} catch (IOException ioe) {lastException = ioe;}}sourceClosed = true;source = null;closed = true;}

在这源码中我们可以看到source就是输入的source,对于Scanner输入的source就是System.in,close()方法中有判断

if (source instanceof Closeable)

instanceof 关键字用法:instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。

因此如果source是Closeable的一个实例,那么source也会被关闭。

 

2、查看System源码(第77行开始)

/*** The "standard" input stream. This stream is already* open and ready to supply input data. Typically this stream* corresponds to keyboard input or another input source specified by* the host environment or user.*/public final static InputStream in = null;

注释部分翻译:

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

----我们还注意到InputStream是被final修饰的----

 

3、查看InputStream源码

我们发现InputStream实现了Closeable接口

(也可直接查看JDK官方文档)

综上,由于InputStream实现了Closeable接口,因此InputStream会被关闭,但是同时InputStream是被final修饰过的,只能被实例化一次,因此我们后面代码再使用System.in也依然是被关闭的。

因此在后面使用的时候会报错:Stream closed

为了避免报错,只好在最后再关闭了


推荐阅读
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文介绍了如何使用 Spring Boot DevTools 实现应用程序在开发过程中自动重启。这一特性显著提高了开发效率,特别是在集成开发环境(IDE)中工作时,能够提供快速的反馈循环。默认情况下,DevTools 会监控类路径上的文件变化,并根据需要触发应用重启。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • MQTT技术周报:硬件连接与协议解析
    本周开发笔记重点介绍了在新项目中使用MQTT协议进行硬件连接的技术细节,涵盖其特性、原理及实现步骤。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
  • 获取计算机硬盘序列号的方法与实现
    本文介绍了如何通过编程方法获取计算机硬盘的唯一标识符(序列号),并提供了详细的代码示例和解释。此外,还涵盖了如何使用这些信息进行身份验证或注册保护。 ... [详细]
  • ###问题删除目录时遇到错误提示:rm:cannotremoveusrlocaltmp’:Directorynotempty即使用rm-rf,还是会出现 ... [详细]
  • 本文详细介绍了Java中的输入输出(IO)流,包括其基本概念、分类及应用。IO流是用于在程序和外部资源之间传输数据的一套API。根据数据流动的方向,可以分为输入流(从外部流向程序)和输出流(从程序流向外部)。此外,还涵盖了字节流和字符流的区别及其具体实现。 ... [详细]
author-avatar
小旋律丶_409
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有