Java

[Java] Optional 클래스 개념 및 사용 방법

cob 2023. 5. 31. 11:15

 

Optional 클래스란?
Java 8에서 추가된 기능으로 값이 존재하지 않는 경우(Null)를 다루는 데 사용된다. 이 클래스는 값이 있을 수도 있고 없을 수도 있는 상황을 나타내는 컨테이너 역할을 하며, NullPointerException과 같은 예외를 방지한다.

 

 

 


1. Optional 클래스 주요 메서드

메서드 설명
Optional<T> Optional 객체를 생성하기 위한 제네릭 타입입니다. T는 값의 타입을 나타냅니다.
Optional.of(value) 지정된 값을 갖는 Optional 객체를 생성합니다. 값이 null이 아닌지 확인하고, null이면 NullPointerException이 발생합니다.
Optional.ofNullable(value) 지정된 값을 갖는 Optional 객체를 생성합니다. 값이 null인 경우에도 예외를 발생시키지 않습니다.
Optional.empty() 빈 Optional 객체를 생성합니다. 값이 없음을 나타냅니다.
isPresent() Optional 객체에 값이 있는지 확인합니다.
get() Optional 객체에 저장된 값을 반환합니다. 값이 없는 경우 NoSuchElementException이 발생합니다.
orElse(defaultValue) Optional 객체에 값이 있는 경우 해당 값을 반환하고, 값이 없는 경우 기본값을 반환합니다.
orElseGet(supplier) Optional 객체에 값이 있는 경우 해당 값을 반환하고, 값이 없는 경우 공급자(Supplier)를 사용하여 기본값을 생성합니다.
orElseThrow(exceptionSupplier) Optional 객체에 값이 있는 경우 해당 값을 반환하고, 값이 없는 경우 예외를 발생시킵니다. 예외 생성을 위해 공급자(Supplier)를 사용합니다.
ifPresent(consumer) Optional 객체에 값이 있는 경우 해당 값을 소비자(Consumer)를 사용하여 처리합니다. 값이 없는 경우 아무 작업도 수행하지 않습니다.

 

 

 


2. 사용 방법

Optional 클래스는 제네릭 타입을 사용하여 값의 타입을 지정할 수 있다.
'Optional<T> ' T는 값의 타입을 나타낸다.

 

2-1) 존재 여부에 따른 처리 방법

import java.util.Optional;

public class OptionalExample {
    public static void main(String[] args) {
        String value = "Hello, Optional!";

        // 1) Optional.of(value)를 사용하여 Optional 객체 생성
        Optional<String> optionalValue = Optional.of(value);
        
        // 2) Optional 객체에 값이 존재 여부 확인
        if (optionalValue.isPresent()) {
            
            // 3) Optional 객체에 저장된 값을 반환
            System.out.println(optionalValue.get());
        }
    }
}

 

2-2) Null 처리 방법

import java.util.Optional;

public class NonNullHandlingExample {
    public static void main(String[] args) {
        String value = "Hello, Optional!";

        // 1) Optional 객체 생성
        Optional<String> optionalValue = Optional.ofNullable(value);
        
        // 2) orElse를 사용하여 null인 경우 기본 값을 반환, null이 아닌 경우 결과 값 반환
        String result = optionalValue.orElse("기본 값");
        System.out.println(result);
    }
}

 

 


3. 활용

3-1)  DB 쿼리 결과 값에 따른 Null 처리

import java.util.Optional;
import javax.persistence.EntityManager;

@Service
public class UserService {
    public Optional<UserDTO> getUserById(Long userId) {
        // MyBatis를 사용해 데이터 조회
        UserDTO user = mybatisMapper.getUserById(userId);
        return Optional.ofNullable(user)
                .orElseThrow(() -> new UserNotFoundException("ID에 해당하는 사용자를 찾을 수 없습니다: " + userId));
    }
}
  • orElseThrow()를 사용하여 null일 경우 UserNotFoundException을 발생 시킨다.

 

3-2) 람다 표현식을 사용해 반복문 활용

@Service
public class TodoService {
    // update
    public List<TodoEntity> update(final TodoEntity entity){
		
		// (1) JPA를 사용해 해당 아이디가 작성한 리스트 조회
		final Optional<TodoEntity> original = repository.findById(entity.getId());
		
		original.ifPresent(todo -> {
			// (2) 새로운 entity 값으로 덮어 씌운다.
			todo.setTitle(entity.getTitle());
			todo.setDone(entity.isDone());
			
			// (3) 데이터베이스에 새 값을 저장한다.
			repository.save(todo);
		});
		// Retrieve Todo에서 만든 메서드를 이용해 사용자의 모든 Todo 리스트를 리턴한다.
		return retrieve(entity.getUserId());
	}
    
    // select
	public List<TodoEntity> retrieve(final String userId){
		log.info("Entity userId : {} is find.", userId);
		return repository.findByUserId(userId);				
	}
 }
  • fPresent 메서드는 Optional 객체에 값이 존재할 경우에만 람다 표현식을 실행한다.

 

 

반응형