What is the use case for null(Input/Output)Stream API in Java?

Naman :

With Java 11, I could initialize an InputStream as:

InputStream inputStream = InputStream.nullInputStream();

But I am unable to understand a potential use case of InputStream.nullInputStream or a similar API for OutputStream i.e. OutputStream.nullOutputStream.

From the API Javadocs, I could figure out that it

Returns a new InputStream that reads no bytes. The returned stream is initially open. The stream is closed by calling the close() method.

Subsequent calls to close() have no effect. While the stream is open, the available(), read(), read(byte[]), ... skip(long), and transferTo() methods all behave as if end of stream has been reached.

I went through the detailed release notes further which states:

There are various times where I would like to use methods that require as a parameter a target OutputStream/Writer for sending output, but would like to execute those methods silently for their other effects.

This corresponds to the ability in Unix to redirect command output to /dev/null, or in DOS to append command output to NUL.

Yet I fail to understand what are those methods in the statement as stated as .... execute those methods silently for their other effects. (blame my lack of hands-on with the APIs)

Can someone help me understand what is the usefulness of having such an input or output stream with a help of an example if possible?


Edit: One of a similar implementation I could find on browsing further is apache-commons' NullInputStream, which does justify the testing use case much better.

Milo Bem :

Sometimes you want to have a parameter of InputStream type, but also to be able to choose not to feed your code with any data. In tests it's probably easier to mock it but in production you may choose to bind null input instead of scattering your code with ifs and flags.

compare:

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

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

with this:

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);
    }
}

or this:

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

It makes more sense with output IMHO. Input is probably more for consistency.

This approach is called Null Object: https://en.wikipedia.org/wiki/Null_object_pattern

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=35029&siteId=1