티스토리 뷰

자바 8에는 다양한 기술들을 살펴보려고 하는데, 그 여섯 번째는 Optional이다.

등장 배경

자바에서는 NullPointerException을 종종 보게 된다.

그 이유는 말 그대로 null 체크를 깜빡했기 때문이다.

Student 클래스를 예로 들어보자.

public class Student {
    private int id;
    private String name;
    private String subject;
    
    public Student() {
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getSubject() {
        return subject;
    }

    public Student(int id, String name, String subject) {
        this.id = id;
        this.name = name;
        this.subject = subject;
    }
}

이 Student 클래스를 빈 생성자로 호출하고 name에 E가 들어가는지 확인하는 코드를 작성한다고 생각해보자.

public class App  {
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student.getName().contains("E"));
    }
}

App을 실행해보면 다음과 같은 NullPointerException이 발생한다.

이처럼 개발자가 의도한 바와 다르게 NullPointerException이 발생하는 상황은 수도 없이 이루어진다.

🤔 위 같은 상황을 방지하기 위해선 어떻게 해야 할까?

1. 예외를 던진다.

public class App  {
    public static void main(String[] args) {
        Student student = new Student();
        String name = student.getName();
        if(name == null) {
            throw new IllegalArgumentException();
        }
    }
}

예외를 던지게 되면 스택트레이스를 찍게 돼서 비용이 많이 드는 단점이 있다.

이펙티브 자바에서 나오는 [아이템 69] 예외는 진짜 예외 상황에서만 사용하라를 참고하자.

2. null 체크를 해주면 된다.

public class App  {
    public static void main(String[] args) {
        Student student = new Student();
        String name = student.getName();
        if(name != null) {
            System.out.println(student.getName().contains("E"));
        }
    }
}

하지만 우리는 사람이므로 위같은 코드를 까먹고 추가를 안 해줄 수 있다.

3. (자바 8부터) Optional을 리턴한다.

Student 클래스에 getName을 다음과 같이 변경해보자.

public Optional<String> getName() {
    return Optional.of(name);
}

이렇게 되면 명시적으로 빈 값일 수도 있다는 걸 알려주고, 빈 값인 경우에 대한 처리를 강제할 수 있다.

주의사항

  • Optional은 리턴값에만 사용하는 게 좋다. ⇒ 특히 Map의 key 타입에는 사용하면 안 된다.
  • Optional을 리턴하는 메서드에서 null 대신 Optional.empty()를 사용하자.
  • 프리미티브 타입용 Optional은 따로 있으니 그걸 사용하자.
    • 내부에서 Boxing, UnBoxing 처리가 돼서 비용 낭비
  • Collection, Map, Stream, Optional은 Optional로 감싸지 않는 것이 좋다.

하지만 이펙티브 자바 [아이템 55] 옵셔널 반환은 신중히 하라에서는 이렇게 말하고 있다.

옵셔널 반환에는 성능 저하가 뒤따르니, 성능에 민감한 메서드라면 null을 반환하거나 예외를 던지는 편이 나을 수 있다.

더 자세한 내용은 이펙티브 자바에서 살펴보면 좋을 것 같다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함