본문 바로가기
Tech/Java

올바른 Optional 사용법

반응형
import java.util.Optional;

Opitonal.of(...);
Optional.ofNullable(...);
Optional.isPresent();
Optional.orElse(...);
Optional.orElseGet(...);
Optional.orElseThrow(...);

만들어진 의도

  • 메서드가 반환할 결과값이 ‘없음’을 명백하게 표현할 필요가 있고, 단 null을 반환하면 에러를 유발할 가능성이 높은 상황이다 그를 해결하고자 메서드의 반환 타입으로 Optional을 사용하자는 것이 주된 목적이다

사용시 주의사항

  1. isPresent()-get() 대신 orElse(), orElseGet(), orElseThrow()
    이왕 비싼 Optional 쓰는김에 코드라도 줄이자!!
// Worst case 
if(Optional.isPresent()){ 
    return ... 
}else{ 
    return ... 
}
// Good case
return Optional.orElse(...);

  1. orElse(new Object..) 대신 orElseGet(()-> new Object…)
    orElse method는 Optional에 값이 있든 없든 무조건 실행한다
    따라서 새로운 객체를 만드는 연산을 수행해야하는 경우는 orElseGet method로 없을때만 사용하게 해야한다

    // Good case 
    Optional.orElseGet(new Object(...));
    // Worst case 
    Optional.orElse(new Object(...));

  1. 단지 값을 얻을 목적이라면 Optional 대신 null 비교
    Optional은 비싸다
    따라서 단순히 값 또는 null을 얻을 목적이라면 Optional 대신 null 비교를 쓰자

    // Good case 
    object != null ? object : ... ;
    // Worst case 
    Optional.ofNullable(object).orElse(...);

  1. 컬렉션을 반환할땐 Optional 대신 비어있는 컬렉션 반환하자
    컬렉션 반환은 null이 아니라 비어있는 컬렉션을 반환하는 것이 좋을 때가 많다
    따라서 컬렉션은 Optional로 감싸서 반환하지 말고 비어있는 컬렉션을 반환하자

    // Good case 
    return Collections != null ? Collections : Collections.emptyList();
    // Worst case 
    return Optional.ofNullable( Collections );

  1. Optional을 필드로 사용 금지
    Optional은 필드에 사용할 목적으로 만들어지지 않았으며, Serializable을 구현하지 않았다
    따라서 Optional은 필드로 사용하지 말자

  1. Optional을 생성자나 메서드 인자로 사용 금지
    Optional을 생성자나 메서드 인자로 사용하면, 호출할 때마다 Optional을 생성해서 인자로 전달해 줘야한다
    굳이 비싼 Optional을 인자로 사용하지 말고 호출되는 쪽 null 체크 책임을 남겨두자 ( Optional은 비싸다.. )

  1. Optional을 컬렉션의 원소로 사용 금지
    컬렉션에는 많은 원소가 들어갈 수 있다
    따라서 비싼 Optional을 원소로 사용하지 말고 원소를 꺼낼때나 사용할 때 null 체크하는 용도로 사용하는 것이 좋다

  1. of(), ofNullable() 혼동주의
    of(X)는 X가 null이 아님이 확실할 때만 사용해야 하며, X가 null이면 NullPointException
    ofNullable(X)는 X가 null일 수도 있을때만 사용해야하며, null이 아님이 확실하면 of(X)를 써야한다

  1. Optional 대신 OptionalInt, OptionalLong, OptionalDouble을 쓰자
    Optional에 담길 값이 int, long, double이라면 Boxing/Unboxing이 발생하는 Optional를 사용하지말고
    OptionalInt, OptionalLong, OptionalDouble을 사용하자
    Boxing, UnBoxing은 성능에 영향을 미친다

추가로 공부해야할 내용

  • Optional이 비싼 이유도 정리해야겠다. (Stream을 이용해서 인걸로 추측중..)

참조 문헌

728x90
반응형