Optional に関する多くの記事では、orElse と orElseGet の違いについて言及しています。おそらく次の例のようになります。
Optional.of("has value").orElse(getDefault()); //do invoke 会执行
Optional.of("has value").orElseGet(() -> getDefault()); // 不会执行
public static String getDefault() {
System.out.println("do invoke");
return "default";
}
- Optonal が空の場合、orElse または orElseGet のいずれかが実行されます。
- Optional に値がある場合、orElse は実行されますが、orElseGet は実行されません。
- 一見したところ、確かに少し混乱しています。明らかに価値があるのに、なぜまだ実行されているのでしょうか? orElse のセマンティクスに違反しているようです。
好奇心から、orElse のソース コードを調べてみました。
public T orElse(T other) {
return value != null ? value : other;
}
最初は理解できず、渡したものがクラス呼び出しで、ここで受け取ったものがオブジェクトだったのですが、急に理解できました。。。
実際、orElse と orElseGet は両方とも対応するメソッドに入ります。そのため、orElse を実行する前に常にパラメーターの値を知る必要があるため、最初に受信したメソッドを実行する必要があります。
実際のトラッキング コードでは、orElse に入る前に getDefault メソッドがすでに実行されていることもわかります。
orElseGet のソース コードを比較すると、orElseGet が実行されない理由が明確になります。
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
よく考えてみると、orElse と orElseGet のセマンティクスが理解できたような気がします。
else値のオブジェクトが存在する場合はorElseを使用してオブジェクトを直接返し、
else値を取得するメソッドの場合はorElseGetを使用します。