Parameter of Optional.orElse gets called even when Optional contains value [duplicate]

那年仲夏 提交于 2020-06-12 15:24:31

问题


The below code prints:

should Not have called
hello world

Why is orElse getting executed even when we have an Optional that contains a value?

public static void main(String[] args){
    String o = Optional.ofNullable("world").map(str -> "hello" + str).orElse(dontCallMe());
    System.out.println(o);
}

private static String dontCallMe() {
    System.out.println("should Not have called");
    return "why god why";
}

回答1:


The orElse method looks like this:

public T orElse(T other) {
   return value != null ? value : other;
}

There isn't any complex logic here.

As with any method, it will do the following:

  • Get the actual values of all parameters passed to the method (which includes calling any methods in those parameters).
  • Pass those parameters to the method.
  • Execute the method.

The fact that we don't actually care about the value of the parameter doesn't change this process (this is just the way the language has been designed, for better or worse).


If you're looking to not call the method in the parameter, you're probably looking for Optional.orElseGet.

This:

public static void main(String[] args){
    String o = Optional.ofNullable("world").map(str -> "hello" + str)
                   .orElseGet(() -> dontCallMe());
    System.out.println(o);
}

private static String dontCallMe() {
    System.out.println("should not have called");
    return "why oh why";
}

Outputs only:

helloworld

The difference here is that the thing (Supplier) we're passing to the method will stay () -> dontCallMe(), it does not become () -> "why oh why" - only when you call get does it actually evaluate what's going on there and does dontCallMe actually get called.




回答2:


Please, can somebody explain why orElse is getting executed event after map will get executed for final result.

With the orElse method regardless if the wrapped value is present or not, the default object is created.

Hence when you call the function dontCallMe() in the orElse to return the string value; "should Not have called" will be printed to the console.

Using orElseGet instead of orElse would provide the result you expected although you should only use this method either when the default value is computationally expensive to create or you want to be sure this is done if and only if the value is absent (empty optional) in which case it's a necessity.

As an aside, there's no need to use Optional.ofNullable here, the Optional.of method is more appropriate as the former should only be used if the argument can be null and the latter only if the argument cannot be null.

As a reading, you can check out this good post on the baeldung site.

Guide To Java 8 Optional



来源:https://stackoverflow.com/questions/49587576/parameter-of-optional-orelse-gets-called-even-when-optional-contains-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!