为什么 InputStream 类里的 close()方法是一个空实现方法? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ubuntuGary
V2EX    Java

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

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

    这是我在 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
    可以理解为能力吧,给子类提供可以自定义关闭的能力的。
    dcuibian
        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     Solana     2742 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 91ms UTC 09:09 PVG 17:09 LAX 02:09 JFK 05:09
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86