求助>Option.orElseGet() 延迟执行的原理是什么?>
2回复
3周前

Option.orElseGet() 延迟执行的原理是什么?



通过 Optional 可以实现 “如果某个值为空则触发另一个逻辑” 这样的效果。

我有个业务场景是:尝试获取某个业务实体,如果获取到的实体为null则走创建逻辑来创建。代码如下:

// 先尝试查找: findBy(someQuery)
// 找不到则创建: someService.creat(someVo)
SomeEntity entity = someService.findBy(someQuery).orElse(someService.creat(someVo));

在调试过程中,我注意到 orElse() 无论如何都会执行内部的表达式,而 orElseGet(Supplier<? extends T> other)中的表达式则会根据 Optional 内部的 value 是否为 null 来决定是否执行。

然后我尝试看一下涉及到 orElseGet 的 class:

    INVOKEDYNAMIC get()Ljava/util/function/Supplier; [
      // handle kind 0x6 : INVOKESTATIC
      java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
      // arguments:
      ()Ljava/lang/Object;, 
      // handle kind 0x6 : INVOKESTATIC
      test/Test.lambda$main$0()Ljava/lang/String;, 
      ()Ljava/lang/String;
    ]
    INVOKESTATIC test/Test.testGet (Ljava/util/function/Supplier;)V

里面是 INVOKEDYNAMIC ,这里没太明白,是 INVOKEDYNAMIC 决定了延迟触发的行为吗?

613 阅读
请先登录,再评论

回复列表

兄弟你想的有点多。跟INVOKEDYNAMIC没有任何关系啊。表达式之所以能够延迟执行是因为orElseGet(Supplier<? extends T> other)参数是一个Supplier 啊 和 orElse是不一样的。例如:
SomeEntity entity = someService.findBy(someQuery).orElseGet(new Supplier () {
SomeEntity get() {
return someService.creat(someVo));
}});
这里入参是一个lambda表达式,那么在这里someService.creat(someVo)是不会执行的。
看一下orElseGet的代码:
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
也就是我们定义的supplier的get方法是在这个方法里调用的,而且value=null时才执行get()方法。

能具体写一个例子不