소프트웨어 엔지니어/개발자라면 늘 주의해야 하는 것이 있다.
바로 null체크를 하는 것이다. null체크는 아주 간단하지만 매우 귀찮다.
또 어떤 경우에는 코드의 심미성을 저하시킨다.
자바 8에서는 lambda와 함께 null체크를 대체 할 수 있는 Optional이라는 클래스를 제공한다.
오늘은 이 Optional의 기본적인 사용방법에 대해 설명하도록 하겠다.
NullPointerException이란?
NullPointerException이란 프로그램이 null인 오브젝트의 멤버에 접근하려 할 때 발생하는 예외상황이다.
예를들어 다음 코드를 보자.
위의 코드에서 Person p = null; // null이 할당 된 것을 볼 수 있다.
이처럼 p에 아무 오브젝트로 할당되지 않았기 때문에 p는 무늬만 Person이고 사실상 아무것도 접근 할 수 없다. 이 코드를 실행시키면,
다음과 같은 예외가 발생한다.
이해가 더 필요하다면 다음의 그림을 보자.
Person p = new Person() 명령어는 내가 Person을 위해 사용 할 공간을 메모리에 할당 한 후, 그 레퍼런스를 p에게 할당하라는 뜻이다. 그러나 Person p = null을 할 경우, p에는 아무런 레퍼런스도 없으므로 실행 시 NullPointerException이 발생하는 것이다.
null 체크 : if ( obj == null )
이런 상황을 막기 위해서 소프트웨어 엔지니어들은 사용하는 오브젝트 들에 대해 항상 null 체크를 한다.
null 체크를 하는 방법은 위처럼 간단하게 if ( obj == null ) 조건문으로 체크 할 수 있다. Java 8에서는 Optional이라는 것을 제공하는데, Optional이란 그냥 어떤 오브젝트의 Wrapper 오브젝트라고 생각하면 이해하기 쉽다.
Optional
Optional은 java.util.Optional 패키지에 있으므로, 해당 패키지를 import하라.
Optional.empty()
위의 예제는 Optional.empty()는 빈 Optional 클래스를 리턴한다.
null을 할당하는 것과 비슷한 느낌이지만 다른 점은 Optional이라는 오브젝트가 생성되고 그 안의 Person이 null이라는 것이다. 따라서 바로 아랫줄의 isPresent()와 같은 api를 사용 할 수 있다. isPresent는 내부에 감싸진 오브젝트가 null이면 false, null이 아니면 true를 리턴한다. 따라서 내부에 Person 오브젝트가 존재하는 경우 조건문 안으로 분기한다. Person 오브젝트가 내부에 존재하는 것을 확인했으므로 get을 이용해 오브젝트를 가져오면 된다. isPresent로 널 여부를 확인했기 때문에 여기서부터는 p가 null이 아님을 확신 할 수 있다.
다시한번 api에 대해 설명하도록 하겠다.
-
Optional<Personal> : 이 Optional클래스는 Person타입의 오브젝트를 저장 할 것.
-
Optional.empty(): Optional 오브젝트를 생성하되 안의 Person은 null로 지정 할 것.
-
isPresent() : Optional안의 Person 오브젝트가 존재하는가?
-
get() : Optional안의 Person 오브젝트를 가져 올 것.
Optional.of(...)
실제로 Person을 가진 Optional 오브젝트를 생성하는 방법은 다음과 같다.
이렇게 하면 Optional의 안에 새 Person 오브젝트를 할당 할 수 있다.
Optional.ofNullable(..)
Optional.of는 내부 오브젝트가 null일 때 쓸 수 없다.
혹시 내부에 들어가는 오브젝트가 null인지 아닌지 확실하지 않다면 Optional.ofNullable을 사용해야 한다. 아래의 예제를 보자.
예제에서 우리는 search 메서드를 이용하여 이름이 같은 Person을 찾아 리턴한다. 같은 이름이 없는 경우에는 null을 리턴한다. 따라서 이 메서드를 사용할 때 오브젝트가 리턴되는지 null이 리턴되는지 확신 할 수 없다. 그럴 때는 위 처럼 Optional.ofNullable을 사용한다.
'■ JAVA > Study' 카테고리의 다른 글
[JAVA] Zip 압축하기 (0) | 2020.10.07 |
---|---|
[JAVA] ObjectMapper 클래스 (0) | 2020.10.07 |
[JAVA] equals() 와 hashCode() ★ (0) | 2020.10.05 |
[JAVA] ArrayList, LinkedList, HashMap, LinkedHashMap, TreeMap, HashSet, LinkedHashSet, TreeSet, Queue, Iterator 설명★★★ (0) | 2020.09.30 |
[JAVA] Path(경로), 파일 읽기,쓰기 ★★★ (0) | 2020.09.30 |