'2015/08/18'에 해당되는 글 1건

  1. 2015.08.18 자바 Null Pointer Exception막는 방법

자바 Null Pointer Exception막는 방법

참조 : http://www.jpstory.net/2014/02/avoid-nullpointerexception/


NPE, Null Pointer Exception 이란?

Null값 때문에 발생하는 Runtime Exception입니다. 

null인 객체에 접근하여 발생하는 예외도 있지만, 그 값이 모호한 경우에 다양한 버그를 만들어냅니다.

예를 들어, 메소드의 호출결과로 null이 반환되었다면 데이터가 없는 것인지, 아니면 메소드의 로직이 실패한 것인지를 정확히 판단하기 힘듭니다. 

어떤 특정한 상황에서 개발자가 일부러 null값을 집어넣을 수도 있기 때문에 null값이 반드시 에러다. 라고는 말할 수 없습니다.

어쨌든 이러한 애매모호한 런타임에러는 디버깅하기 힘들기 때문에, 코드를 작성 할 때 신중히 작성할 필요가 있습니다.

매번 느끼지만 고민을 많이하는 개발자만큼 능력있는 개발자는 없는 것 같습니다. 시간에 쫓기거나 하면서 코딩하는 것이 

얼마나 좋지 않은 것인지에 대해서 매번 깨닫습니다.


Null Pointer Exception을 예방하는 코딩습관에 대해서 설명합니다. 

1) Equals 메소드 사용시

문자열 비교시 non-null String 기준으로 비교합니다. 

equals 메소드는 symmetric하므로 a.equals(b)와 b.equals(a)가 동일합니다. 

절대 널이 발생하지 않는 문자열이 있다면 이를 주 객체로 지정해주는 것이 좋습니다. 


2) toString()보다는 valueOf()를 사용할 것

3) 메소드에서 return null을 사용하지 않기


4) null을 파라미터로 넘기지 말 것


5) 불필요한 autoboxing, unautoboxing 피하기 & Object보다는 기본형 사용하기

6) chaining 메소드 호출 자제하기


Library를 통해서 null pointer exception을 처리해주는 방법

이 사실 더 좋은 방법이라고 생각합니다. 

Apache Commons lang, Google Guava(예전 Google Collections) 등 null safe한 method를 이용하는 방법입니다.

1) Apache Commons의 StringUtils

String의 null 체크를 간단히 할 때 많이 사용하는 클래스입니다. StringUtils.isNotEmpty(), isBlank(), isNumeric(), isWhiteSpace() 등이 있죠.



2) Guava의 Optional 클래스 이용하기

Optional는 nullable한 T를 non-null 값으로 대체시키기 위한 방법인데요. (말이 어렵죠?)
Optional 객체는 non-null인 T reference를 포함하거나 아무것도 포함하고 있지 않습니다.

한마디로 Optional 객체는 명시적으로 null 값을 갖지 않는다는거죠.
NullObject Pattern을 일반화시켰다고나 할까요? 바로 이 점을 이용해서 NPE를 예방합니다.

– absent : 아무 것도 포함하고 있지 않은 상태
– present : non-null 값을 갖은 상태

1) Optional 객체의 생성 (static 메소드)

Optional.of(T)
– T로 받은 non-null 값을 포함하는 Optional 객체 반환, T가 null 일 경우 NPE 발생
Optional.absent()
– 아무것도 포함하고 있지 않는 absent Optional 객체 반환
Optional.fromNullable(T)
– T로 받은 값이 non-null일 경우 present로, null일 경우 absent로 처리한 Optional 객체 반환

2) Optional 객체를 다루기 위한 메소드

boolean isPresent()
– Optional 객체가 non-null 인스턴스를 포함할 경우 true 반환
T get()
– Optional 객체가 present 일 경우 포함하고 있는 인스턴스를 반환, absent일 경우 IllegalStateException 발생
T or(T)
– Optional 객체의 present 값을 반환. 만일 값이 없을 경우 명시한 T를 반환 (기본값)
T orNull()
– Optional 객체의 present 값을 반환, 만일 값이 없을 경우 null을 반환. fromNullable의 역임
Set asSet()
– Optional 객체에서 포함하고 있는 인스턴스의 변경 불가능한 싱글톤 Set을 반환. 만일 인스턴스가 없다면 변경불가능한 Empty set을 반환

3) Guava의 Preconditions 또는 NullPointerTester 클래스 이용하기


Nullness Anotation 활용하기

메소드의 return값 또는 파라미터의 null 허용여부를 Annotation을 이용하여 지정합니다. 코딩 습관 들이기 3, 4번 항목을 제약하기 위해 사용하는데요.

IDE에서 지원하는 @Nullable, @NotNull 등의 Annotation을 사용하면 코드에서 NPE 발생 가능여부를 미리 경고해줍니다. 또 해당 Annotation 제약사항을 위반했을 경우 컴파일시 NPE가 아닌 IllegalArgumentException 또는 IllegalStateException이 발생됩니다. Argument로 NotNull이어야 한다고 정했는데 Null이 들어왔다면 의미상 NPE보다는 잘못된 Argument가 맞겠죠?

현재 ItelliJ, Eclipse IDE 및 Find Bugs에서는 서로 다른 Annotation 라이브러리를 사용하는데요. JCP에 Software Defect Detection하기 위한 Annotation이 JSR-305로 요청 중이나 현재 dormant(중단) 상태네요. 언제 JDK에 포함될런지는 모르겠네요 :'(

Posted by slender ankles
,