【问题标题】:Why ByteArrayOutputStream.close() throws IOException?为什么 ByteArrayOutputStream.close() 会抛出 IOException?
【发布时间】:2016-09-22 20:10:52
【问题描述】:

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

这不是(不重要,但仍然)一个小错误吗?

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

【问题讨论】:

  • 如果定义被改变,捕获IOException的现有代码将得到编译错误Unreachable catch block for IOException. This exception is never thrown from the try statement body
  • @saka1029:我想,你是在正确的轨道上。
  • @saka1029,你是对的(我认为它会导致警告,而不是错误)。

标签: java stream bytearrayoutputstream


【解决方案1】:

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

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

但是这个决定是由很长时间才做出的。还不清楚为什么要添加覆盖,因为继承的 no-op 就足够了,并且覆盖不会更改签名,也不包含该版本中有用的文档改进,即没有说明 close()是不必要的。最合理的解释是添加它是为了删除throws 子句,但随后检测到不兼容是某些现有代码的问题。

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

【讨论】:

  • 我明白,删除它并不重要。
  • 其实答案的主要部分是@saka1029 介绍的:我不知道removing throws 子句真的会引入不兼容。我认为这个事实(删除 throws 子句会引入源不兼容;“Unreachable catch block for ...”是一个错误,而不是警告)本身就是一个错误。
  • @saka1029 的说法是评论(不是回答),所以我不能接受(尽管它首先出现并且很简洁,所以我很想这样做)。跨度>
猜你喜欢
  • 2021-03-05
  • 2012-01-13
  • 2012-09-21
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多