由于ByteArrayOutputStream
只是写入内存,因此永远不会发生IOException
。但是,由于OutputStream
接口的约定,所有流操作都在其IOException
子句中定义throws
。
“处理”这个永不发生的IOException
的正确方法是什么?只需将操作包装在空try-catch
块中?
或者是否有ByteArrayOutputStream
可能引发异常的实际情况?
(另见:How can I handle an IOException which I know can never be thrown, in a safe and readable manner?)
修改
正如Jon指出的那样,ByteArrayOutputStream
没有在它定义的throws
方法上声明write
条款 - 但是,它从write(byte[])
继承了OutputStream
那个人确实抛出IOEXception
(很奇怪,BAOS
不会覆盖这个方法,因为它可以替换超类版本 - 它一次写入一个字节 - 具有更多高效arraycopy
电话)
答案 0 :(得分:10)
好吧,ByteArrayOutputStream
没有声明除了IOException
和writeTo
之外,其任何方法都会抛出close
。 (我不知道为什么close
仍然声明它,说实话。)
如果你有OutputStream
类型的引用,当然你仍会看到抛出声明。
我不会使用空的catch块 - 我会抛出IllegalStateException
之类的东西或类似的未经检查的异常:这意味着你处于真正没有的情况期待,而且出现了严重错误。
答案 1 :(得分:2)
我只是注意到ByteArrayOutputStream.write实际上并没有声明IOException - 但每当我使用它时,Eclipse会抱怨未处理的异常......很奇怪。
这很容易解释。你可能做过这样的事情:
OutputStream os = new ByteArrayOutputStream();
...
os.write();
“问题”是您将方法称为OutputStream.write()
而不是ByteArrayOutputStream.write()
。所以编译器说:
“啊......
write()
OutputStream
可以抛出IOException
,所以你必须处理它。”
不能说:
“此特定
OutputStream
实际上是ByteArrayOutputStream
...所以我们会让你失望。”
因为JLS不允许它。
这是边缘情况之一,通过编码到接口而不是实现类来遵循“最佳实践”回来咬你。
好的......
OutputStream
是作为Java类而不是Java接口实现的,但这不是重点。
答案 2 :(得分:1)
典型的陈词滥调是catch块中的throw new RuntimeException(theIOException)
。如果不可能发生,你至少要了解它。
答案 3 :(得分:1)
异常链接是这种情况下的最佳实践。即抛出RuntimeException。
答案 4 :(得分:1)
自2002年以来,此问题有一个增强ticket。之所以没有解决这个问题,是因为它会影响与以前的java版本的兼容性。
以下是我将考虑的2个解决方法。
write(byte[], int, int)
方法不会抛出已检查的异常。指定2个附加参数有点冗长。但是,如果没有try-catch,所有足迹都会变小。
baos.write(array, 0, array.length);
另一种可能的解决方案是编写自己的ByteUtil
类,它会在内部捕获异常。
public final class ByteUtil
{
public static void write(ByteArrayOutputStream baos, byte[] bytes)
{
try
{
baos.write(bytes);
}
catch (IOException e)
{
// impossible
}
}
}
// usage
ByteUtil.write(baos, bytes);
答案 5 :(得分:1)
自Java 11开始,还有一个new method ByteArrayOutputStream.writeBytes(byte[])
也没有抛出IOException
:
/**
* Writes the complete contents of the specified byte array
* to this {@code ByteArrayOutputStream}.
*
* ...
*
* @since 11
*/
public void writeBytes(byte b[]) {
write(b, 0, b.length);
}
如果不想处理从未抛出的IOException
,则可以使用此方法。