Optional의 등장 이유

자바로 프로그래밍을 하면서 NullPointerException을 안 겪어 본 사람은 없을 것이다. 그만큼 null은 오류를 자주 발생시킬 위험이 있으며 개발하는 입장에서도 상당 귀찮다.

 

null 때문에 발생할 수 있는 문제는 다음과 같다.

1. NullPointerException을 발생시킬 수 있다.

2. 반환된 객체를 처리할 때 if(obj == null){ } 등의 확인 코드가 증가한다. => 가독성이 낮아진다.

 

이러한 점을 해소하고자 등장한 java.util.Optional은 null이 반환되지 않게 하여 오류를 발생시키지 않고, 호출하는 쪽에서도 명시적으로 빈 값이 반환될 수 있음을 알게 하는 것이다.

Optional : 정상적인 결과물인 객체가 반환될 수도 있고, 아니면 빈 값이 반환될 수도 있다는 의미

 

Optional 객체 생성

1. 빈 Optional

Optional<Car> optCar = Optional.empty();

 

2. null이 아닌 객체로 Optional 만들기 : car가 null이라면 NullPointerException이 발생한다.

Optional<Car> otpCar = Optional.of(car);

 

3. null값으로 Optional 만들기 : car가 null이라면 빈 Optional 객체가 반환된다.

Optional<Car> otpCar = Optional.ofNullable(car);

 

Optional 실용 예제

메소드의 결과물로 Optional 반환

DB에서 데이터를 조회하거나 기타 로직으로 생성된 객체를 반환할 때 null이 반환되지 않게 하기 위해 Optional을 반환

// Object를 반환하지 않고 Optional로 한번 감싸서 반환한다.
//  >> Object객체는 빈값(null)이 될 수 있음을 알려준다.
public Optional<Object> getObject(String key){
    return Optional.ofNullable(map.get(key));
}

 

메소드를 호출하는 쪽에서도 if else로 분기하여 처리하지 않고 비즈니스 로직에 따라 처리

비어있는 Optional이 반환되면 Optional의 orEleseGet()으로 빈 객체를 생성하여 반환이 가능하다.

만일 빈 객체가 허용되지 않는다면 orElseThrow()로 오류를 쓰로우하고 종료할 수도 있다.

public Object run(){
    Optional<Object> optValue = getObject("key"); // 위의 getObject()를 호출

    // 1. 빈 객체를 생성하여 반환
    Object value = optValue.orElseGet(Object::new);
}
public Object run(){
    Optional<Object> optValue = getObject("key"); // 위의 getObject()를 호출

    // 2. 오류로 종료
    optValue.orElseThrow(() -> new NoSuchKeyException("해당 키의 값이 없습니다."));
}

 

 

컬렉션은 Optional로 감싸지 말고 빈 컬렉션을 반환

만일 컬렉션 데이터가 없다면 Optional으로 컬렉션을 감싸는 것보다는 빈 컬렉션을 반환하는 것이 효율적이다. (null은 반환하지 않는다.)

// 컬렉션에 데이터가 없으면 Optional로 감싸지 않는다.
List<Object> list = getList();
return Optional.ofNullable(list);

// 대신 빈 컬렉션을 반환한다.
List<Object> list = getList();
return list != null ? list : Collections.emptyList();

 

 

 

 

 

+ Recent posts