11

由于ByteArrayOutputStream只是写入内存,IOException因此永远不会发生。但是,由于OutputStream接口的约定,所有流操作都IOException在其throws子句中定义。

“处理”这种从未发生过的正确方法是什么IOException?简单地将操作包装在一个空try-catch块中?

ByteArrayOutputStream或者是否有任何可能引发异常的实际情况?

(另请参阅:如何以安全且可读的方式处理我知道永远不会抛出的 IOException?

编辑

正如 Jon 所指出的,ByteArrayOutputStream它没有在它定义throws的方法上声明一个子句write——但是,它继承write(byte[])OutputStream,并且确实抛出了IOEXception(很奇怪,它BAOS不会覆盖这个方法,因为它可以替换超类版本——它一次写入一个字节——调用效率更高arraycopy

4

6 回答 6

11

好吧,ByteArrayOutputStream 并没有声明它的任何方法都抛出IOException除了writeToand closeclose(老实说,我不知道为什么仍然宣布它。)

如果你有一个类型的引用,OutputStream当然你仍然会看到 throws 声明。

我不会使用空的 catch 块 - 我会抛出类似IllegalStateException或类似的未经检查的异常:这意味着您处于您真正没想到的情况,并且出现了严重错误。

于 2011-06-07T21:41:17.157 回答
2

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

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

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

“问题”是您正在调用方法 asOutputStream.write()而不是 as ByteArrayOutputStream.write()。所以编译器说:

“啊……write()在一个罐子上OutputStream扔一个IOException,所以你必须处理它。”

它不能说:

“这件事OutputStream真的是ByteArrayOutputStream……所以我们放过你。”

因为 JLS 不允许。

这是通过对接口而不是实现类进行编码来遵循“最佳实践”的边缘情况之一,这会反过来咬你。

好的,所以...

  • 它是一种温和的咬合,而不是完全咬合。
  • OutputStream被实现为 Java 类而不是 Java 接口,但这是无关紧要的。
  • 大多数编译器在编译您的代码时实际上并没有与您进行对话:-)

于 2011-06-08T02:42:13.720 回答
1

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

于 2011-06-07T22:07:58.977 回答
1

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

于 2011-06-07T21:50:05.483 回答
1

自 2002 年以来,有一个针对此问题的增强。此问题未得到修复的原因是它会影响与以前的 java 版本的兼容性。

以下是我会考虑的两种解决方法。

解决方法 1

write(byte[], int, int)方法不会抛出已检查的异常。指定 2 个附加参数有点冗长。但总的来说,如果没有 try-catch,占用空间会更小。

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

解决方法 2

另一种可能的解决方案是编写自己的ByteUtilclass,它在内部捕获异常。

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);
于 2018-06-07T10:35:17.280 回答
1

从 Java 11 开始,还有一个新方法 ByteArrayOutputStream.writeBytes(byte[])也不会抛出 an 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从未抛出的内容,则可以使用此方法。

于 2018-09-13T07:40:30.863 回答