Kam Kam - 23 days ago 4x
Java Question

Why is orGet part of Optional always runs?

class Ideone
public static String test() {
System.out.println("What is this?");
return "Hello";

public static void main (String[] args) throws java.lang.Exception
String result = Optional.ofNullable(new String()).map(c->c.toString()).orElse(Ideone.test());

I expect that
function to never be called. But it is!

output is:
What is this?

was never set to
which is normal, but nevertheless
was called.

Also, when I use
instead, the
will never be called.

Shouldn't the
be called only when the
is needed? The point is if test() is not immutable, then I would've inadvertently mutated by class.


Your argument to orElse is just a plain String — in this case, one that you got by invoking a plain ol' method, Ideone.test(). Conceptually, it's no different from something like:


First the inner expression is evaluated, and then that value becomes the argument for the outer expression.

If you want to defer the method call until you need it, use orElseGet instead, passing it a method reference:

... .orElseGet(Ideone::test);

or, if you prefer:

... .orElseGet( () -> Ideaone.test() );

In English terms, your original code said "... or else, get this String, which I'm providing right now by invoking this function." The method reference version says, "or else, call this method to get a String, and then use that String."