Java 8에서 추가된 Optional 의 메서드인 orElse 와 orElseGet 의 차이점을 확인하고자 한다.
java.util.Optional
T orElse(T other)
T orElseGet(Supplier<? extends T> other)
두 메서드의 시그니처를 보면 반환 타입이 같다. 이름에서 나타내듯이 Optional 의 값이 null
일 경우에 인자로 받은 값(T
)을 반환하는 메서드이다.
하지만, 서로 다른 파라미터를 전달 받는다. orElse 는 반환할 값을 그대로 받는 반면, orElseGet 은 Supplier 로 랩핑한 값을 인자로 받는다.
이는 함수를 전달받아 바로 값을 가져오지 않고lazy 필요할 때 값을 가져온다.
즉, orElseGet 은 null
일 경우에만 함수가 실행되면서 인스턴스화되지만, orElse 는 무조건 인스턴스화 된다.
class LocalTest {
@Test
public void test1() {
Optional.ofNullable(null).orElse(new TestObject("1 ")); (1)
System.out.println();
Optional.ofNullable(new TestObject("2-1 ")).orElse(new TestObject("2-2 ")); (2)
System.out.println();
Optional.ofNullable(null).orElseGet(TestObject::new); (1)
System.out.println();
Optional.ofNullable(new TestObject("4-1 ")).orElseGet(TestObject::new); (3)
}
class TestObject {
TestObject() { System.out.print("new"); }
TestObject(String s) { System.out.print(s == null ? "new" : s); }
}
}
1 2-1 2-2 new 4-1
-
ofNullable
의 인자값으로null
이기 때문에 인스턴스 생성 -
ofNullable
의 인자값이null
이 아니지만new TestObject("2-2 ")
가 실행된다. -
ofNullable
의 인자값이null
이 아니므로TestObject::new
는 동작하지 않는다
Note
|
fb-contrib
|
Conclusion
불필요한 호출을 줄이기 위해 null
일 경우 반환할 값이 primitive type이면 orElse()
, 객체를 생성해야한다면 orElseGet()
를 사용하면 될 것 같다.
int value = Optional.ofNullable(obj1).orElse(123);
TestObject object = Optional.ofNullable(obj2).orElseGet(() -> new TestObject());
TestObject object = Optional.ofNullable(obj2).orElseGet(TestObject::new);