为什么 ByteArrayOutputStream.close() 会抛出 IOException?

Sas*_*sha 5 java stream bytearrayoutputstream

为什么ByteArrayOutputStreamclose是用throws IOException? 首先,事实上它不能扔任何东西,因为它的身体是空的。其次,在法律上它不能抛出任何东西,因为它的文档说“关闭 ByteArrayOutputStream 没有任何效果”。

这不是(不重要,但仍然)有点错误吗?

是的,我知道它的超类OutputStream实现了Closable,其close方法允许 throw IOException。但是没有人禁止使用没有抛出规范的方法覆盖它(in ByteArrayOutputStreamclose。(即使在某些古老的 Java 版本中禁止用更少抛出的方法覆盖更多抛出的方法,现在更改ByteArrayOutputStream.close定义不会是不兼容的更改。)

Hol*_*ger 4

最合理的解释(除了监督)是兼容性。回到Java\xc2\xa01.1,ByteArrayOutputStream 没有重写close()OutputStream,因此它继承了声明 的方法IOException。当时,这可能是一个疏忽。close()也许,开发人员认为这是不必要的,因为无论如何没有人会调用ByteArrayOutputStream。但文档中没有明确说明调用close()是不必要的。

\n\n

由于 Java\xc2\xa01.2 又名 Java\xc2\xa02,ByteArrayOutputStream 确实会覆盖close(). 但是,删除该throws子句会导致代码调用close()aByteArrayOutputStream并捕获已检查的内容,IOException从而在块内的任何其他位置未引发异常时产生编译时错误try。由于这不会影响二进制兼容性,因此考虑到从那时起对源代码级别进行了多少具有更大影响的更改,这可能看起来很奇怪。

\n\n

但这个决定是在很长一段时间里做出的。它\xe2\x80\x99s也不清楚,为什么要添加覆盖,因为继承的无操作就足够了,并且覆盖不会\xe2\x80\x99改变签名,也不\xe2\x80\x99t包含该版本中有用的文档改进,即没有close()不必要的澄清。最合理的解释是,添加它的目的是删除该throws条款,但后来发现不兼容是某些现有代码的问题。

\n\n

最后,删除它\xe2\x80\x99并不重要。如果您的编译时类型是ByteArrayOutputStream,您就知道您不需要调用close(). 在所有其他情况下,即如果编译时类型更通用OutputStream,则必须close()处理声明的IOException\xe2\x80\xa6

\n