본문 바로가기
Java

자바 Optional

by 스르나 2021. 5. 3.

Optional

 

Optional 이란?

자바 개발을 하다보면 항상 격는 문제중 하나는 nullPotinterException이다. 이 예외는 참조변수가 사용될때 참조하고 있는 것이 없이 null인 상태를 의미한다.

 

public class Main {
    public static void main(String[] args) {
        Person person = new Person("jjang gu");

        person=null;

        person.print();
    }
}

 

위 코드는 인위적으로 nullPointerException을 일으킨 것이다. 예제가 단순하지만 우리는 개발을 하다 보면 null값을 제대로 처리하지 않아서 에러를 일으키는 경우를 많이 보았을 것이다.

 

자바에서는 이런 null을 다루기 위해 Optional이라는 클래스를 만들었다.

 

optional

 

Optional은 제너릭을 이용한 클래스다. 즉, T에 해당하는 객체를 감싼 래핑클래스다.

 

public final class Optional<T> {
    /**
     * Common instance for {@code empty()}.
     */
    private static final Optional<?> EMPTY = new Optional<>();

    /**
     * If non-null, the value; if null, indicates no value is present
     */
    private final T value;

 

Optional의 구현체의 일부분이다.

 

Optional로 어떻게 null을 처리하는지를 한 마디로 정의하면 다음과 같다.

 

T는 null일 수도 아닐 수도 있다.

 

Optional로 감싼 T는 null일 수도 아닐수도 있는 null이 될 가능성이 있는 객체를 넣는 것이다.

예를들어 DB에서 어떤 조회(select문)을 통해 값으 받아올때를 생각해보자. 조회에 필요한 파라미터를 넣어서 했는데 이때 값을 반드시 반환해준다는 보장은 없다. 임시로 예를 들어보겠다.

 

public class DataBase {
    
    public Person getPersonByName(String name){
        if(name.equals("jjang gu")){
            return new Person("jjangu");
        }
        return null;
    }
}

자 위의 코드를 DB라고 생각을 해보자. 파라미터로 전해준 문자열이 jjang gu가 아니라면 null을 반환한다.

 

public class Main {
    public static void main(String[] args) {
        Person person=DataBase.getPersonByName("yuri");

        person.print();
    }
}

사용자는 yuri라는 파라미터로 조회를 했으나 결과는 null값이 돌아온다, 이렇게 null값이 예상 되는 곳에 Optional을 통해 해결 할 수 있다.

 

Optional 생성

Optional을 생성하는 법은 2가지가 있다.

1. of

2. ofNullable

 

public class Main {
    public static void main(String[] args) {
        Optional<Person> person=Optional.of(DataBase.getPersonByName("yuri"));
        Optional<Person> person2=Optional.ofNullable(DataBase.getPersonByName("yuri"));
    }
}

 

2의 차이는 of는 안의 값이 null이라면 nullPointerExcption을 일으킨다. 하지만 ofNullable은 일으키지 않는다.

 

Optional 가져오기

 

Optional을 가져오는 방법은 여러가지가 있다.

 

1. get()

2. orElse(Object o)

3. orElseGet(Lambda)

4. orElseThrow(Exception)

 

위의 get부터 설명하면 T가 null이면 예외를 일으키는 것이 전부이다.

 

다음 orElse는 null일 경우 대체로 사용할 객체를 넣는 것이다.

 

다음 orElseGet는 null일 경우 실행할 람다식이 들어 갈 수 있다.

 

public class Main {
    public static void main(String[] args) {
        Optional<Person> person=Optional.ofNullable(DataBase.getPersonByName("yuri"));

        person.get(); //위의 결과가 null 이여서 예외 발생
        person.orElse(new Person("maeng gu")); // maeng gu를 반환
        person.orElseGet(()->new Person("hoon e")); // hoon e를 반환
        person.orElseThrow(NullPointerException::new); // 예외 발생

    }
}

`

추가적으로 isPresent라는 메소드도 존재하는데 이는 null이라면 false를 반환하고 아니면 true를 반환한다.

 

Optional 의 중간 연산

 

Optional도 중간 연산이 가능하다. map, filter를 통해 중간에 값을 바꾸는 것이 가능하다.

 

public class School {
    private Person student;

    public void setStudent(Person student){
        this.student=student;
    }

    public String getStudentName(){
        return Optional.ofNullable(student)
                .map(Person::getName)
                .orElse("temp student");
    }
    
    public int getStudneGrade(){
        return Optional.ofNullable(student)
                .filter(s -> s.getGrade()>=2)
                .map(Person::getGrade)
                .orElse(2);
    }
}

중간 연산을 통해 원하는 값을 이런식으로 받아 올 수 있다.

 

Optional을 좀 더 잘사용하기 위해서는 단순히 null을 처리하기 위한 도구라기 보다는 원소가 1개있는 Stream으로 생각해야 한다.

 

'Java' 카테고리의 다른 글

자바 Exception  (0) 2021.10.09
String,StringBuilder,StringBuffer  (0) 2021.03.10
Collection Framework 정리표  (0) 2021.02.25
자바 synchronized 이해  (0) 2021.02.24
JVM  (0) 2021.02.14