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

Why ByteArrayOutputStream.close() throws IOException?

为什么 ByteArrayOutputStream.close 是用 throws IOException 声明的? 首先,事实上它不能抛出任何东西,因为它的 body 是空的。其次,在法律上它不能抛出任何东西,因为它的文档说 "closing a ByteArrayOutputStream has no effect".

这不是(non-important,但还是)有点错误吗?

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

最合理的解释(除了疏忽)是兼容性。回到 Java 1.1,ByteArrayOutputStream did not override close(),因此它继承了 OutputStream 的方法,该方法声明了 IOException。当时,这可能是一个疏忽。也许,开发人员认为这是不必要的,因为无论如何没有人会在 ByteArrayOutputStream 上调用 close()。但是文档缺少关于调用 close() 是不必要的明确声明。

自 Java 1.2 又名 Java 2,ByteArrayOutputStream does override close()。但是删除 throws 子句会导致代码在 ByteArrayOutputStream 上调用 close() 并捕获已检查的 IOException 以在任何其他异常未抛出时产生编译时错误放置在 try 块中。由于这不影响二进制兼容性,考虑到自那时以来对源代码级别进行了多少影响更大的更改,这可能看起来很奇怪。

但这个决定是很久以前做出的。同样不清楚的是,为什么要添加覆盖,因为继承的空操作就足够了,覆盖不会更改签名,也不包含该版本中有用的文档改进,即没有关于 [=11 的说明=] 是不必要的。最合理的解释是添加它的目的是删除 throws 子句,但随后检测到不兼容是某些现有代码的问题。

归根结底,删除它并不重要。如果你的编译时类型是 ByteArrayOutputStream,你知道你不需要调用 close()。在所有其他情况下,即如果编译时类型是更通用的 OutputStream,您必须 close() 并处理声明的 IOException