Optional Unwrap

이규훈·2025년 2월 2일
        // 저장되어 있는 유저를 찾음
        var userEntity = userEntityRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException(username));
        User.from(userEntity);

해당 코드는 에러가 안생겼고

        Optional<UserEntity> byUsername = userEntityRepository.findByUsername(username);
        User.from(byUsername);

해당 코드는 컴파일 에러가 생기고 있다.

💡 원인 분석: Optional 처리 방식의 차이

두 코드의 핵심 차이는 Optional을 올바르게 처리했는지 여부입니다.
var 키워드 자체가 문제가 아니라, Optional을 언랩(unwrap)했는지 여부에 따라 컴파일 에러가 발생합니다.


1. 정상 작동하는 코드 (컴파일 에러 없음)

var userEntity = userEntityRepository.findByUsername(username)
        .orElseThrow(() -> new UsernameNotFoundException(username)); // ✅ Optional을 UserEntity로 언랩
User.from(userEntity); // ✅ UserEntity 전달
  • 동작:
    findByUsername()Optional<UserEntity>를 반환합니다.
    orElseThrow()를 통해 Optional 내부의 UserEntity를 추출합니다.
    userEntityUserEntity 타입이 됩니다.
    User.from(userEntity)UserEntity를 인자로 받으므로 정상 동작합니다.

2. 컴파일 에러가 발생하는 코드

Optional<UserEntity> byUsername = userEntityRepository.findByUsername(username); // ❌ Optional을 그대로 저장
User.from(byUsername); // ❌ Optional을 UserEntity 대신 전달
  • 문제점:
    byUsernameOptional<UserEntity> 타입입니다.
    User.from()UserEntity를 인자로 기대하지만, Optional을 전달했기 때문에 타입 불일치로 인한 컴파일 에러가 발생합니다.

🔥 var 키워드는 타입을 추론할 뿐, 동작을 변경하지 않습니다.

var byUsername = userEntityRepository.findByUsername(username); // 타입: Optional<UserEntity>
User.from(byUsername); // ❌ 여전히 Optional을 전달 → 컴파일 에러
  • 결론:
    varOptional<UserEntity>byUsername에 할당하므로,
    User.from()에 전달할 때 여전히 타입 불일치 에러가 발생합니다.
    var를 사용해도 Optional 처리 로직이 없다면 동일한 에러가 발생합니다.

해결 방법: Optional을 언랩(unwrap)해야 합니다.

// 방법 1: orElseThrow() 사용
Optional<UserEntity> byUsername = userEntityRepository.findByUsername(username);
UserEntity userEntity = byUsername.orElseThrow(() -> new UsernameNotFoundException(username));
User.from(userEntity);

// 방법 2: ifPresent() 활용 (추가 로직 필요 시)
byUsername.ifPresent(userEntity -> {
    User.from(userEntity);
});

📌 핵심 정리

  • var ≠ 타입 문제 해결: var는 단지 타입을 명시하지 않을 뿐, 실제 타입은 컴파일러가 추론합니다.
  • Optional 핸들링: **반드시 orElseThrow(), orElse(), ifPresent() 등을 사용해 값을 추출해야 합니다.
  • 컴파일 에러 방지: 메서드가 기대하는 파라미터 타입과 전달하는 타입이 일치해야 합니다.
profile
개발취준생

0개의 댓글