자바 변수에는 생성한 오브젝트(객체)를 가리키는 참조형 타입의 변수가 있습니다.

아래 Integer 타입의 num변수를 선언 후 할당하는 경우입니다.

Integer num; // Integer 타입의 변수 num을 선언, 초기화 하지 않음
num = new Integer(10); // new 키워드를 사용해 Integer 객체를 생성후 num에게 참조시킴

첫째 줄은 Integer 타입의 num 변수를 선언했습니다. 참조형 변수를 선언만 했으므로 'null'로 초기화됩니다.

null 이란 참조형 변수가 아무것도 가리키지 않는 상태라는 의미입니다. 

두번째 줄에서 num에 세로운 Integer 객체를 생성하여 참조시켰습니다. 이로써 num은 null 에서 새로운 Integer 객체를 가리키도록(Integer 객체의 주소값이 할당) 변경되었습니다.

 

NullPointerException(아래부터는 줄여서 NPE라고 하겠습니다.)은 첫 번째 줄처럼 선언만 하고 아무것도 참조하지 않는 null 상태인 변수에서 내용을 참조하려 할 때 발생합니다.

 

내용을 참조한다는 것은 점(.)으로 객체 변수에 접근하는 것을 말합니다.

아래 코드는 null인 변수 k에 점(.)으로 indexOf() 함수를 호출하려 할 때 NPE가 발생합니다.

아무것도 가리키지 않는 상태인데 내부 내용에 접근하려 하니 오류가 나는 것이지요.

public void NPE_method1(){
    String k = null;
    k.indexOf(1);
}

 

컴파일러가 해당 참조변수는 아직 초기화 되지 않았다는 메시지를 표출하기도 하지만 아래와 같은 코드에서는 null이 넘어올지 초기화된 참조변수가 넘어올지 알 수 없습니다. 만일 doSomething(null); 로 호출하게 되면 NPE 오류가 나게됩니다. 

public void doSomething(SomeObject obj) {
   obj.myMethod();
}

 

이런 경우에는 어떻게 하여야 할까요?

제일 좋은 방법은 메서드 시작전에 obj가 초기화 되었는지 검증하는 것입니다.

doSomething 함수의 내부로직이 obj가 초기화 되었다는 것을 전제로 작성되었다면, 첫 줄에 null 값에 대한 검증 후 만일 null이 넘어온 경우 처리할 수 없다는 명시적인 메시지와 함께 종료하는 것이죠.

import java.util.Objects;

public class Test {
    public static void main(String[] args) {
        new Test().doSomething(null);
    }

    public void doSomething(Object obj){
        Objects.requireNonNull(obj, "obj는 null값이 아니여야 합니다.");
    }
}
Exception in thread "main" java.lang.NullPointerException: obj는 null값이 아니여야 합니다.

 

doSomething 내에서 obj에 null값을 허용하며 분기하여 처리할 수도 있습니다. 다음 코드를 참조해주세요.

public void doSomething(Object obj){
    if(obj == null){
        // obj가 null일 때의 로직
    }else {
        // obj를 이용한 로직
    }
}

 

 


 

 

+ Recent posts