본문 바로가기
Java 웹 프로그래밍

Java 8 Null과 Optional - 1

by irerin07 2020. 1. 17.
728x90

Java 8 Null과 Optional -2 - https://irerin07.tistory.com/108

 

코딩을 하다보면 자주 마주치는 Exception중에 하나인 NullPointerException.

이 예외는 객체가 들어와야 하는 곳에 null을 사용하려고 할 때 발생하며 다음과 같은 몇가지 경우가 있다.

- null object의 인스턴스 메소드를 호출할 때

- null object의 필드에 접근하거나 수정하려 할 때

- Array처럼 null의 길이를 가져오려 할때

- Array처럼 null의 slots에 접근하거나 수정하려 할 때

- null을 마치 Throwable value처럼 사용할 때

자바에서는 위와 같이 null에 접근하려 하면 NullPointerException을 발생시키고 이를 해결하기 위해서 개발자들은

Null Check를 강요당해왔다.

위 그림과 같은 Computer 구조체가 있다고 가정해보자.

String version = computer.getSoundcard().getUSB().getVersion();

위의 코드가 무엇을 의미하는지는 알기 쉽다.

하지만 이 코드를 Sound card가 없는 컴퓨터에 적용하게 되면 무슨 결과값이 나올지 생각해보자.

대다수의 개발자들은 soundcard가 없다는 것을 표현하기 위해 null을 리턴할테고 결국 getUSB()는 null을 참조하는 USB를 반환하여 NullPointerException이 발생하게 된다.

결국, 프로그램은 멈추게 된다.

 

프로그램을 정지합니다. 정지하겠습니다. 되잖아?

String version = "UNKNOWN";
if(computer != null){
  Soundcard soundcard = computer.getSoundcard();
  if(soundcard != null){
    USB usb = soundcard.getUSB();
    if(usb != null){
      version = usb.getVersion();
    }
  }
}

무수히 많은 null check의 요청이...!!

 

이를 해결하기 위해 가장 좋은 방법은 value가 null값을 가질 수 없도록 하는 것이지만 사실 쉽지만은 않다.

적지 않은 수의 개발자들은 아무것도 없는 값을 포현하기 위해 null을 사용했고,

이를 확인하기 위한 null check는 필수가 되어버렸기 때문이다.

 

Java8은 이 문제들을 해결하기 위한 새로운 Class, java.util.Optional을 추가했다.

Optional은 Haskell의 Maybe, 그리고 스칼라의 Option에서 아이디어를 얻어 추가 된 클래스이다.

optional은 값을 포함하거나 포함하지 않는 단일 값 컨테이너이고 optional값을 캡슐화 하는 클래스이다.

Soundcard를 가질수도, 아무것도 없을수도 있는 Optional

public class Computer {
  private Optional<Soundcard> soundcard;  
  public Optional<Soundcard> getSoundcard() { ... }
  ...
}

public class Soundcard {
  private Optional<USB> usb;
  public Optional<USB> getUSB() { ... }

}

public class USB{
  public String getVersion(){ ... }
}

위 코드에서 보이듯이 Computer는 Soundcard를 가질수도 있고 가지지 않을수도 있고 Soundcard역시 USB를 가질수도, 가지지 않을수도 있다.

이를 통해 우리는 해당 값들이 필수인지 아닌지를 쉽게 알 수 있다.

 

Optional클래스는 모든 null 참조를 대신하려는것이 아니다.

그보다는 보다 이해하기 쉬운 API를 디자인하는 것이 목적이다.

Optional이 요구하는것은 개발자로 하여금 값이 없는 경우에 어떻게 해야할지 생각하게 하여 의도치 않은 NullPointerException을 원천차단하는것에 있다.

 

728x90