Java:写入ByteArrayOutputStream时的IOException?

问题描述 投票:9回答:6

由于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?

编辑

正如乔恩所指出的那样,ByteArrayOutputStream没有声明它定义的throws方法的write条款 - 但是,它继承了write(byte[])OutputStream,而且确实抛出IOEXception(很奇怪BAOS不会覆盖这种方法,因为它可以替换超类版本 - 一次写入一个字节 - 使用更高效的arraycopy调用)

java exception ioexception outputstream bytearrayoutputstream
6个回答
10
投票

好吧,ByteArrayOutputStream没有声明它的任何方法抛出IOException除了writeToclose。 (我不知道为什么close仍然声明它,说实话。)

如果你有一个OutputStream类型的引用,当然你仍然可以看到抛出声明。

我不会使用一个空的catch块 - 我会抛出像IllegalStateException或类似的未经检查的异常:它意味着你处于一种你真的没有想到的情况,而且出现了严重错误。


2
投票

我只是注意到ByteArrayOutputStream.write实际上并没有声明IOException - 但每当我使用它时Eclipse都会抱怨未处理的异常......很奇怪。

这很容易解释。你可能做过这样的事情:

    OutputStream os = new ByteArrayOutputStream();
    ...
    os.write();

“问题”是你将方法称为OutputStream.write()而不是ByteArrayOutputStream.write()。所以编译器说:

“啊...... write()上的OutputStream可以抛出一个IOException,所以你必须处理它。”

它不能说:

“这个特别的OutputStream真的是一个ByteArrayOutputStream ......所以我们会让你失望。”

因为JLS不允许它。

这是通过编码到接口而不是实现类的“最佳实践”回到咬合你的边缘情况之一。

好的......

  • 它是一个温柔的压区,而不是一个完整的咬合。
  • OutputStream实现为Java类而不是Java接口,但这不是重点。
  • 在编译代码时,大多数编译器实际上并没有与您进行对话:-)


1
投票

一个典型的陈词滥调是在阻挡块中的throw new RuntimeException(theIOException)。如果不可能发生,你至少要了解它。


1
投票

在这种情况下,异常链接是最佳实践。即抛出RuntimeException。


1
投票

自2002年以来,这个问题有一个增强的ticket。之所以没有得到解决,是因为它会影响与以前的java版本的兼容性。

这里有两个我会考虑的解决方法。

Workaround 1

write(byte[], int, int)方法不会抛出已检查的异常。指定2个附加参数有点冗长。但是,如果没有try-catch,所有足迹都会更小。

baos.write(array, 0, array.length);

Workaround 2

另一种可能的解决方案是编写自己的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);

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,则可以使用此方法。

© www.soinside.com 2019 - 2024. All rights reserved.