Why ByteArrayOutputStream
.close
is declared with throws IOException
?
First, de facto it can't throw anything, because its body is empty. Second, de jure it can't throw anything, because its documentation says "closing a ByteArrayOutputStream has no effect".
Isn't this (non-important, but still) a little mistake?
Yes, I understand that its superclass OutputStream
implements Closable
, the close
method of which is allowed to throw IOException
. But nobody forbids to override it (in ByteArrayOutputStream
) with close
method with no throw specification. (Even if overriding a more-throwing method with a less-throwing method was forbidden in some ancient versions of Java, changing ByteArrayOutputStream
.close
definition now won't be incompatible change.)
The most plausible explanation (besides oversight) is compatibility. Back in Java 1.1,
ByteArrayOutputStream
did not overrideclose()
, so it inherited the method fromOutputStream
which declaresIOException
. Back then, it might have been an oversight. Perhaps, the developers thought that this is unnecessary as nobody is going to callclose()
on aByteArrayOutputStream
anyway. But the documentation lacks an explicit statement about callingclose()
being unnecessary.Since Java 1.2 aka Java 2,
ByteArrayOutputStream
does overrideclose()
. But removing thethrows
clause would cause code callingclose()
on aByteArrayOutputStream
and catching the checkedIOException
to produce a compile-time error when the exception is not thrown at any other place within thetry
block. Since this doesn’t affect the binary compatibility, it might look strange considering how much changes with more impact were made on the source code level since then.But this decision was made a long time age. It’s also unclear, why the override was added at all, as the inherited no-op was sufficient and the override doesn’t change the signature and also doesn’t contain a useful documentation improvement in that version, i.e. no clarification about
close()
being unnecessary. The most plausible explanation is that it was added with the intent of removing thethrows
clause, but then it was detected that the incompatibility was an issue with certain existing code.In the end, it’s not really important to remove it. If your compile-time type is
ByteArrayOutputStream
, you know that you don’t need to callclose()
. In all other cases, i.e. if the compile-time type is the more generalOutputStream
, you have toclose()
and handle the declaredIOException
…