Java 中 null(Input/Output)Stream API 的用例是什么?

使用Java 11,我可以初始化一个as:InputStream

InputStream inputStream = InputStream.nullInputStream();

但是我无法理解 InputStream.nullInputStream 或类似 API 的潜在用例,即 OutputStream.nullOutputStreamOutputStream

从API Javadocs中,我可以弄清楚它

返回不读取字节的新值。返回的流最初处于打开状态。通过调用 close() 方法关闭流。InputStream

后续调用不起作用。当流处于打开状态时,、 、 、 ... 和方法的行为都像已到达流的末尾一样。close()available()read()read(byte[])skip(long)transferTo()

我进一步浏览了详细的发行说明,其中指出:

有很多时候,我想使用需要目标 OutputStream/Writer 作为参数来发送输出的方法,但希望以静默方式执行这些方法以获得其他效果。

这对应于 Unix 中将命令输出重定向到 /dev/null 或 DOS 中将命令输出追加到 NUL 的功能。

然而,我不明白声明中的这些方法是什么,如....以静默方式执行这些方法以获得其他效果。(归咎于我缺乏API的实践)

如果可能的话,有人可以帮助我理解在示例的帮助下拥有这样的输入或输出流有什么用处吗?


编辑:我在进一步浏览时可以找到的类似实现之一是apache-commons的NullInputStream,它确实更好地证明了测试用例的合理性。


答案 1

有时,您希望具有 InputStream 类型的参数,但也希望能够选择不向代码提供任何数据。在测试中,模拟它可能更容易,但在生产中,您可以选择绑定空输入,而不是用s和标志分散代码。if

比较:

class ComposableReprinter {
    void reprint(InputStream is) throws IOException {
        System.out.println(is.read());
    }

    void bla() {
        reprint(InputStream.nullInputStream());
    }
}

有了这个:

class ControllableReprinter {
    void reprint(InputStream is, boolean for_real) throws IOException {
        if (for_real) {
            System.out.println(is.read());
        }
    }
    void bla() {
        reprint(new BufferedInputStream(), false);
    }
}

或者这个:

class NullableReprinter {
    void reprint(InputStream is) throws IOException {
        if (is != null) {
            System.out.println(is.read());
        }
    }
    void bla() {
        reprint(null);
    }
}

恕我直言,输出更有意义。输入可能更是为了保持一致性。

此方法称为空对象https://en.wikipedia.org/wiki/Null_object_pattern


答案 2

我认为它是一种更安全(1)和更具表现力(2)的替代方法,而不是用.null

  1. 不用担心 NPE。
  2. [Output|Input]Stream是一个抽象。为了返回空/空/模拟流,您必须从核心概念向下偏离到特定的实现。

推荐