When using Optional
s, whatever code is provided in the .orElse
will be executed everytime the Optional
is evaluated, not just when the Optional
is empty and the .orElse
would be hit. Sometimes people make the mistake of putting code in the .orElse
that has a side effect that can affect performance (e.g. making a database query to get some kind of default value) or can result in bugs (e.g. running a database query that updates some value that should only be done when the Optional
is empty). In these cases .orElseGet
should be used as it defers execution until the Optional
actually evaluates to empty and the .orElseGet
needs to be run.
See also this popular StackOverflow thread on .orElse
vs .orElseGet
where the delayed execution is referenced as one of the main differences
Non-Compliant code:
Optional.ofNullable(getSpecificItemFromDB(itemId))
.orElse(getDefaultItemFromDB())
This will call getDefaultItemFromDB()
every time this optional is called, even if getSpecificItemFromDB
returns a non-null value.
Compliant code:
Optional.ofNullable(getSpecificItemFromDB(itemId))
.orElseGet(() -> getDefaultItemFromDB())
Now getDefaultItemFromDB
is only called if getSpecificItemFromDB
returns a null value.
To pick up on this, sonar could inspect the contents of .orElse
and check if the value is constant or not