상세 컨텐츠

본문 제목

[Java] Optional 타입이란??

개발 공부/Java

by 양양츄 2024. 3. 2. 16:24

본문

java언어 기반으로 spring 프로젝트를 만들면서 공부하다보면 Optional 이라는 타입을 만나게되더라

 

우선 Optional은  값이 없는 경우를 표현하기 위해서 사용한다.

아래와 같은 대표적인 메서드가 있다.

of() : 값이 null이 아닌 경우에만 Optional 객체를 생성

ofNullable() : 값이 null인 경우에도 Optional 객체를 생성.

empty() : 값을 갖지 않는 빈(empty) Optional 객체를 생성.

 

Optional 객체에 접근할 때에는 .isPresent() 메서드를 사용해야한다.

일반적인 .get() 메서드를 사용하면 값이 없는 경우에 예외가 발생할 수 있기 때문이다.

??? 앞서 "값이 없는 경우를 표현하기 위해서 사용한다" 면서 이게 무슨말인가?

오해할 수 있지만, 값이 없는 경우를 표현 하는것이지, 값이 없는것을 반환한다는 뜻이 아니다.

즉,

.isPresent() 메서드를 값의 존재 여부를 확인하는 것이다.

 

 

아래에 코드는 <인프런 김영한 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB접근 기술> 강의 중 한 부분이다

public interface MemberRepository {
    Member save(Member member);
    Optional<Member> findById(Long id);
    Optional<Member> findByName(String name);
    List<Member> findAll();
}



public class MemoryMemberRepository implements MemberRepository {

    private static Map<Long, Member> store = new HashMap<>();
    private static long sequence = 0L;


    @Override
    public Member save(Member member) {
        member.setId(++sequence);
        store.put(member.getId(), member);
        return member;
    }

    @Override
    public Optional<Member> findById(Long id) {
        // Optional.ofNullable
        // id값이 null(없더라도)이여도 사용할 수 있도록 해준다
        return Optional.ofNullable(store.get(id));
    }

    @Override
    public Optional<Member> findByName(String name) {
        return store.values().stream().filter(member -> member.getName().equals(name)).findAny();

    }

    @Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values());
    }

    public void clearStore() {
        store.clear();
    }
}

 

 

선언된 interface MemberRepository를 MemoryMemberRepository 클래스가 상속받아서 사용할 수 있는데,

상위 클래스( MemberRepository )에서 선언된 메서드를 사용하기 위해 오버라이딩을 사용하게 된다.

.ofNullable() 메서드를 사용해서 값이 없더라도 객체 생성하도록 설계.

MemberService에서 Service 처리할때 .isPresent() 사용해서 값의 존재를 확인, 처리


//MemoryMemberRepository (레파짓토리 로직수행)
@Override
public Optional<Member> findById(Long id) {
    // Optional.ofNullable
    // id값이 null(없더라도)이여도 사용할 수 있도록 해준다
    return Optional.ofNullable(store.get(id));
}


//MemberService (서비스 처리)
public long join(Member member) {
        //같은 이름이 있는 중복 회원X
//      Optional<Member> result = memberRepository.findeByName(member.getName());
//      result.ifPresent(m -> {
//          throw new IllegalStateException("이미 존재하는 회원입니다.");
//      });
        // 위 코드를 아래처럼 바꿀 수 있다.
        // ctrl+alt+shift+T -> Extract Method 메서드 화 시킴.
        validateDuplicateMember(member);

        memberRepository.save(member);
        return member.getId();
    }

    // 중복 이름 회원가입 불가
    // ctrl+alt+shift+T -> Extract Method 메서드 화 시킴.
    private void validateDuplicateMember(Member member) {
        memberRepository.findByName(member.getName()).ifPresent(m -> {
            throw new IllegalStateException("이미 존재하는 회원입니다.");
        });
    }

관련글 더보기