public T orElse(T other) {
return value != null ? value : other;
}
해당 값이 null이거나 null이 아니어도 실행된다.
public T orElseGet(Supplier<? extends T> supplier) {
return value != null ? value : supplier.get();
}
해당 값이 null 일때만 실행된다.
orElse
는 값이 null이든 null이 아니든 실행되고 orElseGet
은 값이 null일 때만 실행된다고 하였는데 메서드들의 구현부를 보면 알겠지만 값이 null이든 null이 아니든 orElse와 orElseGet은 항상 실행된다.
orElse
와 orElseGet
에 메서드가 파라미터 전달되는 경우public void javaOptionalCheck() {
String checkName = “myName”;
String result = Optional.ofNullable(checkName).orElse(defaultName());
System.out.println(“first result is ” + result);
result = Optional.ofNullable(checkName).orElseGet(this::defaultName);
System.out.println(“second result is ” + result);
}
private String defaultName() {
System.out.println("return defaultName");
return "default name";
}
return defaultName
first result is myname
second result is myname
orElse
의 경우 전달된 메소드는 값이 아니라 값을 return해주는 존재이다. 따라서 orElse
에서는 메서드를 먼저 실행시키게 된다.Url url = urlRepository.findByUrl(requestedUrl)
.orElse(urlRepository.save(new Url(requestedUrl, 0)));
위의 코드는 DB에서 url이 존재하는지 확인하고 존재하지 않을 경우 url을 DB에 저장하는 코드이다. 당연히 url은 DB에서 UNIQUE 조건이 걸려 있다. orElse
의 경우 메소드가 아닌 값이 필요하기에 DB에서 url 존재 여부와 상관 없이 urlRepository.save(new Url(requestedUrl, 0)
를 호출할 것이고 이는 UNIQUE contraint를 위반하여 문제를 발생시킬 것이다. 따라서 이러한 문제를 일으키고 싶지 않다면 아래와 같이 코드를 수정해야 한다.
Url url = urlRepository.findByUrl(requestedUrl)
.orElseGet(() -> urlRepository.save(new Url(requestedUrl, 0)));