Java 8의 Optional에 보면 orElse
와 orElseGet
두 가지 메소드가 존재하는데 무슨 차이가 있을까?
아래 Optional 클래스를 보면 두 개의 메소드를 확인할 수 있다.
public T orElse(T other) {
return value != null ? value : other;
}
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
orElse
는 값이 null일 경우 T 타입을 반환해주고 orElseGet
은 값이 null인 경우 Supplier에서 값을 꺼내서 리턴한다.
반환되는 타입도 T 타입으로 같으니 null일 경우 받는 매개변수만 다른것일까?
이 두 가지 메소드는 잘 구분하여 사용해야 한다고 구글링에서 많이 이야기한다. 그래서 실제 동작을 테스트 해보았다.
결론은 아래와 같다.
- orElse는 리턴값이 null 여부와 상관없이 항상 호출된다.
- orElseGet은 리턴값이 null인 경우만 호출된다.
아래는 테스트 코드이다.
orElse
@Test
public void orElseTest() {
String name = "hong";
String result = Optional.ofNullable(name).orElse(getDefault());
System.out.println(result);
}
private String getDefault() {
System.out.println("no name");
return "no name";
}
// 출력 메시지
no name
hong
여기서 orElse 파라미터는 값이 null이 아닐 경우에도 실행된다는 것을 확인할 수 있다.
orElseGet
@Test
public void orElseGetTest() {
String name = "hong";
String result = Optional.ofNullable(name).orElseGet(this::getDefault);
System.out.println(result);
}
private String getDefault() {
System.out.println("no name");
return "no name";
}
// 출력 메시지
hong
orElseGet은 인수로 Supplier를 받는데 Supplier가 매개변수로 넘겨질 때는 Optional 값이 존재하지 않을때만 실행된다.
위의 예에서 볼 수 있듯이 orElse
인 경우는 null 여부와 상관없이 무조건 호출 되므로 조심해서 사용해야 한다.
예를 들면 리턴값이 null인 경우 DB에 특정 정보를 update한다던가, 이벤트를 전송하는 등의 작업은 하지 않아야 한다.
// 이렇게 사용하면 안된다.
public User findUser(String userId) {
return userRepository.findById(userId).orElse(createUser(userId)); //
}
private void createUser(String userId) {
userRepository.save(new User(userId));
}
반응형