web-dev-qa-db-ja.com

Reactor Mono <Void>が空のMonoとして認識されるのはなぜですか?

これがコードの一部です

_@Test
public void test_mono_void_mono_empty() {
    Mono.just("DATA")
        .flatMap(s -> Mono.just(s.concat("-")
                                 .concat(s))
                          .doOnNext(System.out::println)
                          .then())
        .switchIfEmpty(Mono.just("EMPTY")
                           .doOnNext(System.out::println)
                           .then())
        .block();
}
_

次の結果がコンソールに表示されます。

_DATA-DATA
EMPTY
_

つまり、最初のflatMapのチェーンは空のチェーンとして認識されました。

一方、Reactorには次のクラス MonoEmpty があり、Mono.empty()method によって返されます。その上、メソッドは次のように述べています。

_/**
 * Create a {@link Mono} that completes without emitting any item.
 *
 * <p>
 * <img class="marble" src="doc-files/marbles/empty.svg" alt="">
 * <p>
 * @param <T> the reified {@link Subscriber} type
 *
 * @return a completed {@link Mono}
 */
public static <T> Mono<T> empty() {
    return MonoEmpty.instance();
}
_

アイテムを放出せずに-Void型付きオブジェクトをthen()メソッドで放出しました。

その説明は何ですか?

3
povisenko

さて、答えは official Java doc にあり、The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword voidと書かれています。

つまり、その主な目的は、単にvoid戻り値の型をクラスとして表し、Class<Void>パブリック値を含めることです。それでおしまい。さらに、コンストラクターはプライベートであるため、インスタンス化できません。その後のすべては、Void変数に割り当てることができる唯一の値がnullであり、常にempty Monoとして認識されることを意味します。

役立つディスカッション: Javaジェネリックvoid/Void型

6
povisenko

指定されたMonoは、完了信号を送信する前に、何も発行しないか、単一の値を発行できます。 (これはnullを公開できません-リアクティブ仕様では禁止されています。)Monoのジェネリック型はmightが発行されるオブジェクトの型を示しますが、保証はありませんwillが発行される。

たとえば、_Mono<Foo>_は、完了信号のみ、またはFooのインスタンスとその後の完了信号を発行できます。

値が公開されない一般的なシナリオは2つあります。1つ目は、値が存在する場合と存在しない場合(データベースまたはコレクション内のアイテムの検索など)です。その場合でも、_Mono<SomeType>_を使用することになり、SomeTypeインスタンスが出力される場合とされない場合があります。 2番目のシナリオは、値が確実に公開される(つまり、タスクが完了したという通知が必要な場合によく使用される)neverであり、そのために慣例により、常に_Mono<Void>_が使用されます。上記の例では、then()は2番目のケースに該当します。

_Mono<Void>_が特殊なケースである理由は、ご指摘のとおり、Voidは設計によってインスタンス化できないクラスであるためです。したがって、Voidのインスタンスなどはありません。つまり、Monoは、完了信号の前に値を発行することはできません。

したがって、論理的な結論は、タイプ_Mono<Void>_のパブリッシャーは値を発行できず、完了信号のみを発行できるため、そのように使用されるということです。

0
Michael Berry