본문 바로가기

Java

Optional에 대하여

자바를 사용하면서 Null Pointer Exception를 만나본 적이 있는 사람들은 null 처리를 위한 분기를 작성할 것이다.

자바 8에서 이러한 분기를 코드 흐름은 가독성에 방해가 된다 생각하여 Optional을 도입하였다.

 

Optional은 한 마디로 정의내린다면 null일 수도 있는 값이다. 즉, 값이 없거나 (null) 있거나 둘 중 하나란 소리다.

Optional에 구현된 메서드들은 null이 아니라면 동작하도록 구현되어 있다. 이를 통해 복잡한 null 처리 분기를 작성하지 않고, 순차적인 흐름으로 코드를 읽도록 도와준다.

 

예제를 통해 살펴보자.

public class Manager{
	List<Car> cars = new ArrayList();
    public Car getCar(int idx){
        if(idx >= cars.size()){
        	return null;
        }
        return cars.get(idx);
    }
}

Manager 클래스에서 특정 인덱스의 원소를 조회하는 코드를 작성했다. 값이 리스트 크기보다 크다면 null을 반환하는데, 메서드를 호출하는 입장에서는 두 가지 경우를 고려하여 작성해야 한다. 하지만 Optional을 사용하면 다음과 같이 변경할 수 있다.

Optinal<Car> car = Optional.ofNullable(manager.getCar(n));
//값이 있다면 Optinal의 Chaning된 메서드를 수행하여 값을 얻는다.
//1. car.orElse
//2. car.orElseGet
//3. car.orElseThrow
//등등.. null이면 더 이상 수행하지 않고 else문을 수행시킬 수도 있다.

 

주의할 점

- Optional을 도입한다면 null을 절대 반환하면 안된다. 도입 취지를 무시하는 행동이기 때문이다.

- 컬렉션을 반환한다면 Optional로 감쌀 필요가 없다. 컬렉션의 원소가 없다면 그 자체로 비어있다는 의미이기 때문이다.

- Optional도 wrapping class이기 때문에 엄연히 primitive보다 성능 차이가 날 수 밖에 없다. 성능이 중요하다면, 박싱된 기본 타입을 담는 옵셔널은 지양하고, OptionalInt, OptionalLong 등과 같이 전용 옵셔널 클래스를 지향하자.