[Java] Optional 개념 및 사용법

태빵·2022년 2월 6일
1

java

목록 보기
2/2

클린코드에서는 null을 반환하는 것을 지양한다. 그렇게 암묵적으로 동의하는 것만드로도 불필요한 null check 를 방지할 수 있다.

  • 불필요한 null check 예시 - clean code 예시.. null check하느라 바쁘다 바뻐...
public void registerItem(Item item) {
    if (item != null) { 
    	ItemRegistry registry = peristentStore.getItemRegistry(); 
        if (registry != null) { 
		    Item existing = registry.getItem(item.getID()); 
		    if (existing.getBillingPeriod().hasRetailOwner()) { 	
	    	existing.register(item); 
    	    } 
	    }
	} 
}

java 8 부터는 Optional 개념을 도입하여 이러한 문제를 해결하려 한다.

java.util.Optional<T> 클래스

Optional 클래스는 'T'타입의 객체를 포장해 주는 래퍼 클래스(Wrapper class)

  • 따라서 Optional 인스턴스는 모든 타입의 참조 변수를 저장할 수 있음
  • NullPointerException 예외를 제공되는 메소드로 간단히 회피
  • 만약 Optional 객체에 저장된 값이 null이면, NoSuchElementException 예외가 발생

사용법

메소드설명
static Optional empty()아무런 값도 가지지 않는 비어있는 Optional 객체를 반환함.
T get()Optional 객체에 저장된 값을 반환함.
boolean isPresent()저장된 값이 존재하면 true를 반환하고, 값이 존재하지 않으면 false를 반환함.
static Optional of(T value)null이 아닌 명시된 값을 가지는 Optional 객체를 반환함.
static Optional ofNullable(T value)명시된 값이 null이 아니면 명시된 값을 가지는 Optional 객체를 반환하며, 명시된 값이 null이면 비어있는 Optional 객체를 반환함.
T orElse(T other)저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 값을 반환함.
T orElseGet(Supplier<? extends T> other)저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 람다 표현식의 결괏값을 반환함.
T orElseThrow(Supplier<? extends X> exceptionSupplier)저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 예외를 발생시킴.

예시

  • 일반적인 클래스
class LunchBox {
    private LunchBox lunchBox;

    public LunchBox getLunchBox() {
        return lunchBox;
    }
}

class Beverage {
    private Beverage beverage;

    public Beverage getBeverage() {
        return beverage;
    }
}

class Person {
    private String name;

    public String getName() {
        return name;
    }
}
  • 여기서 클래스를 연속적으로 접근하고자 한다면?
Person person = new Person(); 
String beverageName = person.getName().getBeverage().getLunchBox(); //npe 발생
  • Optional 을 사용이여 이를 회피한다.
class LunchBox {
    private Optional<LunchBox> lunchBox = Optional.empty();

    public Optional<LunchBox> getLunchBox() {
        return lunchBox;
    }
}

class Beverage {
    private Optional<Beverage> beverage = Optional.empty();

    public Optional<Beverage> getBeverage() {
        return beverage;
    }
}

class Person {
    private String name;

    public String getName() {
        return name;
    }
}
// 호출 법
Person person = new Person(); 
String beverageName = person.getName() 
    .flatMap(LunchBox::getLunchBox) 
    .map(Beverage::getBeverage) 
    .orElse("unknown");

올바른 Optional 사용법 가이드

  • Optional 변수에 Null을 할당하지 말아라
  • 값이 없을 때 Optional.orElseX()로 기본 값을 반환하라
  • 단순히 값을 얻으려는 목적으로만 Optional을 사용하지 마라
  • 생성자, 수정자, 메소드 파라미터 등으로 Optional을 넘기지 마라
  • Collection의 경우 Optional을 사용하지 말고 빈 Collection으로 처리하라
  • 반환 타입으로만 사용하라

출처: https://mangkyu.tistory.com/203 [MangKyu's Diary]

참고

클린코드, NULL을 반환하거나 인수로 전달하지 마라. 그리고 Java 8 Optional

tcpschool

[Java] 언제 Optional을 사용해야 하는가?

[자바 고급 스터디 1주차 - 3부] Stream과 Optional

profile
hello world

0개의 댓글