很多关于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
都会执行getDefault()
方法; - 当
Optional
有值时,orElse
会执行,而orElseGet
不会执行。
乍一看确实有点懵,明明有值,为什么还执行,这跟orElse
的含义违背啊。
怀着好奇心,我看了下orElse
的源码:
public T orElse(T other) {
return value != null ? value : other;
}
这里我们回想下自己平时调试代码时经常看到,一些方法调用传参处为了方便直接是写了一个方法调用,为的就是获取返回值,将方法返回值作为一个参数传递到外层方法里。
所以orElse传入一个方法无论有没有值都会被调用的本质原因在于在解析这一行代码时,参数中涉及的方法会被先执行,把这个说是orElse
和orElseGet
的区别其实有点把人往误区引。
那反过来对比看下orElseGet
的源码就更清楚了:
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
因为它接受的是一个Supplier
对象, 所以在执行orElseGet
语句时不会调用其内部方法。
那我们来分析下orElse
和orElseGet
真正的区别在哪,其实就是方法给大家的第一印象
- 当else的值是现有变量时直接使用
orElse
直接返回该对象; - 而当else的值需要进一步计算才能获取到时使用
orElseGet