为什么 Reactor Mono<Void> 被识别为一个空的 Mono?
Why Reactor Mono<Void> is recognized as an empty 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 具有以下 class MonoEmpty that is returned by a 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();
}
没有发出任何项目 - 但我用 then()
方法发出了 Void
类型的对象。
这是什么解释?
好的,答案在 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 return 类型表示为 class 并包含一个 Class<Void>
public 值。而已。此外,它不可实例化,因为构造函数是私有的。所有这一切随后意味着我们可以分配给 Void
变量的唯一值是 null
始终被识别为 empty Mono
.
有益的讨论:
Java generics void/Void types
给定的 Mono
可以在发送完成信号之前不发布任何内容或单个值。 (它不能发布 null
- 反应规范禁止它。) Mono
的泛型类型表示 可能 被发射的对象的类型 -但不能保证它 会 被发射。
例如,Mono<Foo>
可以只发出一个完成信号,或者 Foo
的一个实例,然后发出一个完成信号。
有两种可能无法发布值的常见情况 - 第一种是值可能存在也可能不存在(例如在数据库或集合中搜索项目)。在那种情况下,您仍然会使用 Mono<SomeType>
,它可能会或可能不会发出 SomeType
实例。第二种情况是,如果某个值肯定 永远不会 被发布(通常在您只需要通知任务已完成时使用),那么按照惯例,Mono<Void>
是总是被使用。 then()
,在你上面的例子中,属于第二种情况。
Mono<Void>
是特例的原因是,正如您所指出的,Void
是一个 class,永远无法通过设计实例化。因此,不存在 Void
的实例,这意味着 Mono
永远不会在其完成信号之前发出值。
因此,合乎逻辑的结论是 Mono<Void>
类型的发布者永远不会发出值,只能发出完成信号 - 因此它被用作这样。
这是一段代码
@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 具有以下 class MonoEmpty that is returned by a 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();
}
没有发出任何项目 - 但我用 then()
方法发出了 Void
类型的对象。
这是什么解释?
好的,答案在 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 return 类型表示为 class 并包含一个 Class<Void>
public 值。而已。此外,它不可实例化,因为构造函数是私有的。所有这一切随后意味着我们可以分配给 Void
变量的唯一值是 null
始终被识别为 empty Mono
.
有益的讨论: Java generics void/Void types
给定的 Mono
可以在发送完成信号之前不发布任何内容或单个值。 (它不能发布 null
- 反应规范禁止它。) Mono
的泛型类型表示 可能 被发射的对象的类型 -但不能保证它 会 被发射。
例如,Mono<Foo>
可以只发出一个完成信号,或者 Foo
的一个实例,然后发出一个完成信号。
有两种可能无法发布值的常见情况 - 第一种是值可能存在也可能不存在(例如在数据库或集合中搜索项目)。在那种情况下,您仍然会使用 Mono<SomeType>
,它可能会或可能不会发出 SomeType
实例。第二种情况是,如果某个值肯定 永远不会 被发布(通常在您只需要通知任务已完成时使用),那么按照惯例,Mono<Void>
是总是被使用。 then()
,在你上面的例子中,属于第二种情况。
Mono<Void>
是特例的原因是,正如您所指出的,Void
是一个 class,永远无法通过设计实例化。因此,不存在 Void
的实例,这意味着 Mono
永远不会在其完成信号之前发出值。
因此,合乎逻辑的结论是 Mono<Void>
类型的发布者永远不会发出值,只能发出完成信号 - 因此它被用作这样。