영권's

자바 (Optional) 본문

자바/JAVA

자바 (Optional)

ykkkk 2021. 8. 1. 23:46

Optional은 자바8에서 새로 추가된 인터페이스이다.

 

Optional이 나오게 된 이유

 

null을 반환하면 별도의 null 처리를 해야하며 null 처리를 무시하고 반환된 null 값을 어딘가에 저장하면 언젠가 NPE가 발생한다. 그것도 근본적인 원인, 즉 null을 반환하게 한 실제 원인과는 전혀 상관없는 코드에서...

 

null 값을 참조하려고 하는 경우 NPE 가 나오게 된다.

이런 에러는 보통 if(progress != null)과 같이 조건문을 사용해서 해결하게 된다.

하지만 이런 방법은 사람이 코딩하는데 있어서 에러를 만들기 쉬운 코딩 방법중 하나이다.

해결하는 방법은 아주 간단하지만 근본적인 이유를 해결하는 것이 아니다. (사람이 코딩하는 것이기 때문에 실수를 해서 널 체크를 하지 않을 수 도 있다.)

 

두 번째 이유는 널을 리턴하는 것 자체가 문제.

만약 리턴값이 특별한 상황에서 값을 제대로 리턴할 수 없는 경우 해결하는 경우는 예외를 던지거나 그냥 null을 리턴한다.

예외를 던지는 경우에는 스택트레이스를 찍기 때문에 리소스가 비싸다. 때문에 진짜 예외적인 상황에서만 사용해야 한다.

 

null을 리턴하는 것은 자바8부터 Optional을 이용해서 명시적으로 표현할 수 있다.

(클라이언트 코드에게 명시적으로 빈 값일 수 도 있다는 것을 알려주고, 빈 값인 경우에 대한 처리를 강제한다.)

 

Optional

  • 오직 한 개가 들어 있을 수도 없을 수도 있는 컨테이너이다.

Optional에 객체를 담는 것인데 null인 경우 넣은 객체가 없을 수 도 있다.

    // 원래 코드
    public Progress getProgress() {
        return progress;
    }
    
    // Optaional로 리턴타입을 감싼 코드
	public Optional<Progress> getProgress() {
        
        // 널인 경우 optional에 아무것도 값이 없는 것과 같이 처리
        // null 일 수 있는 값을 리턴하는 경우 
        return Optional.ofNullable(progress); 
        
        //return Optional.of(progress); // null이 아니라고 확실한 값을 리턴하는 경우 of 사용
    }

 

※주의 사항

  • 리턴값으로만 쓰기를 권장 (메서드 매개변수 타입, 맵의 키 타입, 인스턴스 필드 타입으로 쓰지 말기)
    • 예로 메서드 파라미터 타입으로 Optional로 감싸서 사용하는 것은 문법적으로는 문제가 없지만, null이 넘어오거나 하는 문제가 발생할 수 있다. Optional를 사용하는 의미가 없다 오히려 번거러워 짐.
    • 맵의 키 타입을 Optional로 사용한다면 맵의 키가 가진 특징을 깨뜨리는 상황이다.
      • 맵의 키 값은 null 아닙니다. 를 Optional를 사용함으로 맵의 키 값이 비어있을 수도 있다?? 라는 것이 된다. 정말 안좋은 코드가 발생할 수 있다.
    • 인스턴스 필드 타입으로 Optional를 사용할 경우 설계를 다시 고려해볼 필요가 있음.
  • Optional을 리턴하는 메서드에서 null을 리턴하지 말자.
    • null를 리턴하면 Optional를 사용하는 의미가 없어진다.
    • Optional이 만들어진 이유를 다시 생각하면 당연히 하면 안되는 결과이다.
    • 만약 return 값이 없다면 Optional의 empty()를 활용
  • 프리미티브 타입용 Optional이 따로 있다. ex) OptionalInt, OptaionalLong...
    • Optional.of(10) 과 같이 기본형 타입을 넣을 수 있으나 내부적으로 boxing, unboxing이 많이 발생하기 때문에 성능이 좋지 않다.
  • Collection, Map, Stream Array, Optional은 Optional로 감싸지 말자.
    • 다른 컨테이너 성격의 인스턴스를 감싸지 않는다. 
    • 비어있는 것을 표현할 수 있는 타입들인데 굳이 Optional로 감싸서 굳이 일을 두번 할 필요가 없다.

 

 

출처 : 백기선 - 더 자바, Java 8 ( https://www.inflearn.com/course/the-java-java8?inst=6fcc1e30 )

이펙티브 자바 - 아이템55

'자바 > JAVA' 카테고리의 다른 글

Java - Stream  (0) 2021.09.19
CompletableFuture  (0) 2021.08.09
JAVA 인터뷰 대비  (0) 2020.10.25
JVM  (0) 2020.10.14
JAVA - 업캐스팅과 다운캐스팅 (형변환)  (0) 2020.05.29
Comments