Java 11では、InputStream
を次のように初期化できます。
_InputStream inputStream = InputStream.nullInputStream();
_
しかし、 _InputStream.nullInputStream
_ の潜在的なユースケース、またはOutputStream
の同様のAPI、つまり _OutputStream.nullOutputStream
_ を理解できません。
API Javadocsから、それがわかる
reads no bytesという新しい
InputStream
を返します。返されるストリームは最初は開いています。 close()メソッドを呼び出すと、ストリームが閉じられます。
close()
への後続の呼び出しは効果がありません。ストリームが開いている間、available()
、read()
、read(byte[])
、...skip(long)
、およびtransferTo()
メソッドはすべて、ストリームの終わりに到達したかのように動作します。
詳細なリリースノート をさらに詳しく説明しました。
出力を送信するためにターゲットOutputStream/Writerをパラメーターとして必要とするメソッドを使用したいが、他の効果のためにそれらのメソッドをサイレントに実行したい場合があります。
これは、コマンド出力を/ dev/nullにリダイレクトするUnixの機能、またはコマンド出力をNULに追加するDOSの機能に対応します。
しかし、... =と記述されているステートメントのthose methodsが何であるか理解できません。他の効果のためにこれらのメソッドを静かに実行します。 (APIのハンズオンの欠如を非難)
可能であれば、例の助けを借りて、そのような入力または出力ストリームを持つことの有用性を理解するのを誰かが助けてもらえますか?
Edit:さらにブラウジングで見つけることができる同様の実装の1つはApache-commonsです NullInputStream
。テストユースケースをはるかに正当化します。
InputStream型のパラメーターが必要な場合がありますが、データにコードを入力しないことも選択できます。テストでは、おそらくモックを作成する方が簡単ですが、実稼働環境では、コードをif
sとフラグで分散させる代わりに、バインドnull入力を選択できます。
比較する:
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);
}
}
出力IMHOの方が理にかなっています。入力はおそらく一貫性のためです。
このアプローチはNull Objectと呼ばれます: https://en.wikipedia.org/wiki/Null_object_pattern
null
でストリーム変数を初期化するよりも安全(1)で表現力豊か(2)の代替手段だと思います。
[Output|Input]Stream
は抽象化です。 null/empty/mockストリームを返すためには、コアの概念から特定の実装まで逸脱する必要がありました。nullOutputStream
は非常に簡単で明確だと思います:出力を破棄するだけです(> /dev/null
)および/またはテスト用(OutputStream
を作成する必要はありません)。
(明らかに基本的な)例:
OutputStream out = ... // an easy way to either print it to System.out or just discard all prints, setting it basically to the nullOutputStream
out.println("yeah... or not");
exporter.exportTo(out); // discard or real export?
nullInputStream
に関しては、おそらく入力ストリームを必要とするAPI(私はモックが好きではありません)や、データを含まない入力ストリームを配信する(現在はより可能性が高い)テスト用です。 null
は実行可能なオプションではありません。
importer.importDocument("name", /* input stream... */);
InputStream inputStream = content.getInputStream(); // better having no data to read, then getting a null
そのインポーターをテストするときは、独自のnullInputStream
を発明する代わりに、またはモックを使用する代わりに、InputStream
を使用できます。ここでのその他の使用例は、APIの回避策または誤用のように見えます;-)
InputStream
の戻りに関して:それはむしろ理にかなっています。データがない場合は、nullInputStream
の代わりにnull
を返すと、呼び出し元がnull
を処理する必要がなく、次のように読み取ることができます。データがありました。
最後に、これらは別の依存関係を追加せずに私たちの生活を楽にする単なる便利なメソッドです;-)と他の既に述べたように(コメント/回答)、それは基本的に nullオブジェクトパターン の実装です。
null*Stream
には、テストをより高速に実行できるという利点もあります。実際のデータをストリームする場合(もちろん、サイズなどに応じて)、テストを不必要に遅くするだけで、すべてのテストを高速で完了させたい場合、正しい? (一部はここにモックを入れます...まあ...)