V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ubuntuGary
V2EX  ›  Java

为什么 InputStream 类里的 close()方法是一个空实现方法?

  •  
  •   ubuntuGary · 2022-03-20 21:28:53 +08:00 · 2310 次点击
    这是一个创建于 977 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这是我在 jdk11 里看到的源码

        /**
         * Closes this input stream and releases any system resources associated
         * with the stream.
         *
         * <p> The <code>close</code> method of <code>InputStream</code> does
         * nothing.
         *
         * @exception  IOException  if an I/O error occurs.
         */
        public void close() throws IOException {}
    
    9 条回复    2022-03-21 12:23:34 +08:00
    mineralsalt
        1
    mineralsalt  
       2022-03-20 21:39:25 +08:00
    因为 InputStream 不能直接实例化, 都有具体的子类, 子类会复写这个方法
    ubuntuGary
        2
    ubuntuGary  
    OP
       2022-03-20 21:52:50 +08:00
    @mineralsalt 不实现不是更好,提示子类必须实现,现在 InputStream 写了个空实现,子类继承时没有了强制要求。
    之所以会这样推断,是因为
    ···java
    public abstract class InputStream implements Closeable {}
    ···
    mineralsalt
        3
    mineralsalt  
       2022-03-20 21:57:52 +08:00
    @ubuntuGary 不需要强制子类实现啊, 如果你设计的子类不需要 close, 那就忽略这个函数呗
    xy90321
        4
    xy90321  
       2022-03-20 22:05:17 +08:00 via iPhone
    close 本就可以啥都不做,没有从 SDK 层面必须释放的 handle
    ubuntuGary
        5
    ubuntuGary  
    OP
       2022-03-20 22:26:18 +08:00
    @mineralsalt
    @xy90321
    谢谢,大概有点明白了,应该是我想当然了,以为所有的 InputStream 子类都需要 close ,如果没有 SDK 层面上就要求必须 close 的话,在 InputStream 实现个空 close 方法,去除 Closeable 接口的强制实现要求,给 InputStream 子类更大的自由。另外,我在想是不是也有 java 语法的向下兼容考虑,是不是某个低版本的 jdk 里 InputStream 就是没有实现 Closeable 接口声明的,现在有了 try-with-resources 新特性后,加上了实现 Closeable 接口声明,而为了兼容没有 close 方法的旧版本 InputStream 子类代码,才在 InputStream 类里写了个空 close 方法
    DonaldY
        6
    DonaldY  
       2022-03-20 22:29:13 +08:00
    可以理解为能力吧,给子类提供可以自定义关闭的能力的。
    dcsuibian
        7
    dcsuibian  
       2022-03-20 22:52:44 +08:00
    个人看法:close()这个方法吧,主要是用来销毁外部资源的。其实外部资源一般就是内存以外的资源,如文件、网络连接等。而内存是由 GC 控制的,其实不需要你手动销毁。
    InputSteam 的实现类不一定需要 close(),参考 ByteArrayInputStream 。所以这样写就避免了子类需要重写 close()的麻烦。(不过 ByteArrayInputStream 流好像还是用空方法重写了下)
    fkdog
        8
    fkdog  
       2022-03-20 23:29:20 +08:00
    InputStream 用了设计模式力的模板模式,其中有一个抽象方法 int read()是需要子类去实现的,剩余的方法子类可以直接使用父类的默认实现。
    InputStream 最主要的功能就是从流中读取数据,不同的流类型有不同的 read 方法,所以这个方法强制子类去实现。
    至于其他的 close()一类的,子类不一定需要关闭,所以就不强制你 close()了。比如 ByteArrayInputStream 就不需要关闭,因为他本身就是 ByteArray 的一个封装,可以交给虚拟机 GC 处理。
    seakingii
        9
    seakingii  
       2022-03-21 12:23:34 +08:00
    InputStream 是的抽象类,它描述了能做什么,但没有具体的说明怎么做。
    这里也很现实,你自己写,文件流和网络流的关闭行为能在细节一致吗?一个是关闭文件句柄,一个是关闭网络。甚至有些流根本没有东西要关闭。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1030 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 19:33 · PVG 03:33 · LAX 11:33 · JFK 14:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.