2016-09-22 167 views
1

为什么ByteArrayOutputStreamclosethrows IOException一起声明? 首先,事实上它不能扔任何东西,因为它的身体是空的。其次,它在法律上不能抛出任何东西,因为它的文档说“关闭一个ByteArrayOutputStream不起作用”。为什么ByteArrayOutputStream.close()抛出IOException?

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

是的,我知道它的超类OutputStream执行Closableclose方法允许投掷IOException。但是没有人禁止用close方法覆盖它(在ByteArrayOutputStream中),并且没有throw规范。 (即使覆盖更抛出法用投掷少法在一些古老的版本的Java禁止,改变ByteArrayOutputStreamclose定义现在不会是不兼容的变化。)

+2

如果定义改变它赶上IOException异常将得到编译错误,现有代码'无法到达catch块为IOException。这个异常永远不会从try语句体中抛出。 – saka1029

+0

@ saka1029:我想,你走在正确的轨道上。 – Holger

+0

@ saka1029,你是对的(我认为这会导致警告,而不是错误)。 – Sasha

回答

2

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

由于Java 1.2又名Java 2,ByteArrayOutputStreamdoes override close()。但是删除throws子句将导致在ByteArrayOutputStream上调用close()的代码,并在try块内的任何其他位置未引发异常时捕获检查的IOException以产生编译时错误。由于这不会影响二进制兼容性,因此考虑到源代码级别对影响程度有多大影响后会发生多大变化,这可能看起来很奇怪。

但是这个决定是做了很长一段时间。也不清楚,为什么要添加覆盖,因为继承的空操作已经足够,并且覆盖不会改变签名,也不会在该版本中包含有用的文档改进,即不需要关于close()的说明。最合理的解释是,它添加了删除throws子句的意图,但后来发现不兼容性是某些现有代码的问题。

最后,删除它并不重要。如果您的编译时类型为ByteArrayOutputStream,则知道您不需要拨打close()。在其他情况下,即如果编译时类型是更普遍的OutputStream,你必须close()并办理申报IOException ...

+0

我明白,删除它并不重要。 – Sasha

+0

实际上,答案的主要部分是由@ saka1029引入的:我不知道* remove * throws子句真的会引入不兼容。我认为这个事实(删除一个throws子句可能会引入源不兼容;“无法访问的catch块...”是一个错误,而不是一个警告)本身就是一个错误。 – Sasha

+0

@ saka1029的声明是一条评论(不是答案),所以我不能接受它(尽管它首先出现并且很简洁,所以我非常想这么做)。 – Sasha

相关问题