Just for completness, the "several variables" case is indeed possible, though not elegant at all. For example, for variables o, p, and q:
Optional.ofNullable( o ).orElseGet(()-> Optional.ofNullable( p ).orElseGet(()-> q ) )
Please note the use of orElseGet() attending to the case that o, p, and q are not variables but expressions either expensive or with undesired side-effects.
In the most general case coalesce(e[1],e[2],e[3],...,e[N])
coalesce-expression(i) == e[i] when i = N
coalesce-expression(i) == Optional.ofNullable( e[i] ).orElseGet(()-> coalesce-expression(i+1) ) when i < N
This can generate expressions excessively long. However, if we are trying to move to a world without null, then v[i] are most probably already of type Optional<String>, as opposed to simply String. In this case,
result= o.orElse(p.orElse(q.get())) ;
or in the case of expressions:
result= o.orElseGet(()-> p.orElseGet(()-> q.get() ) ) ;
Furthermore, if you are also moving to a functional-declarative style, o, p, and q should be of type Supplier<String> like in:
Supplier<String> q= ()-> q-expr ;
Supplier<String> p= ()-> Optional.ofNullable(p-expr).orElseGet( q ) ;
Supplier<String> o= ()-> Optional.ofNullable(o-expr).orElseGet( p ) ;
And then the whole coalesce reduces simply to o.get().
For a more concrete example:
Supplier<Integer> hardcodedDefaultAge= ()-> 99 ;
Supplier<Integer> defaultAge= ()-> defaultAgeFromDatabase().orElseGet( hardcodedDefaultAge ) ;
Supplier<Integer> ageInStore= ()-> ageFromDatabase(memberId).orElseGet( defaultAge ) ;
Supplier<Integer> effectiveAge= ()-> ageFromInput().orElseGet( ageInStore ) ;
defaultAgeFromDatabase(), ageFromDatabase(), and ageFromInput() would already return Optional<Integer>, naturally.
And then the coalesce becomes effectiveAge.get() or simply effectiveAge if we are happy with a Supplier<Integer>.
IMHO, with Java 8 we will see more and more code structured like this, as it's extremely self-explainatory and efficient at the same time, especially in more complex cases.
I do miss a class Lazy<T> that invokes a Supplier<T> only one time, but lazily, as well as consistency in the definition of Optional<T> (i.e. Optional<T>-Optional<T> operators, or even Supplier<Optional<T>>).