
참조값 없이 객체를 찾아가면 NullPointerException이라는 예외가 발생한다.
NullPointerException은 이름 그대로 null을 가리키다(Pointer)인데, 이때 발생하는 예외(Exception)다.
null은 없다는 뜻이므로 결국 주소가 없는 곳을 찾아갈 때 발생하는 예외이다.
객체를 참조할 때는 .(dot)을 사용한다. 이렇게 하면 참조값을 사용해서 해당 객체를 찾아갈 수 있다. 그런데 참조값이 null이라면 값이 없다는 뜻이므로, 찾아갈 수 있는 객체(인스턴스)가 없다.
NullPointerException은 이처럼 null에 .(dot)을 찍었을 때 발생한다.
package ref;
public class NullMain2 {
public static void main(String[] args) {
Data data = null;
data.value = 10; // NullPointerException 예외 발생
System.out.println("data = " + data.value);
}
}
data 참조형 변수에는 null값이 들어가 있다. 그런데 data.value = 10이라고 하면 어떻게 될까?
data.value = 10;
null.value = 10; // data에는 null 값이 들어있다.
결과적으로 null 값은 참조할 주소가 존재하지 않는다는 뜻이다. 따라서 참조할 객체 인스턴스가 존재하지 않으므로 다음과 같이 java.lang.NullPointerException이 발생하고, 프로그램이 종료된다. 예외가 발생했기 때문에 그 다음 로직은 수행되지 않는다.

지역 변수의 경우, null 문제를 파악하는 것은 어렵지 않다. 하지만 멤버 변수가 null인 경우에는 주의가 필요하다.
package ref;
public class Data {
int value;
}
package ref;
public class BigData {
Data data;
int count;
}
package ref;
public class NullMain3 {
public static void main(String[] args) {
BigData bigData = new BigData(); // x001
System.out.println("bigData.count = " + bigData.count);
System.out.println("bigData.data = " + bigData.data);
System.out.println("bigData.data.value = " + bigData.data.value);
}
}


BigData를 생성하면 BigData의 인스턴스가 생성된다. 이 때 BigData 인스턴스의 멤버 변수에 초기화가 일어나는데, BigData의 data 멤버 변수는 참조형이므로 null로 초기화 된다. count 멤버 변수는 숫자이므로 0으로 초기화된다.
bigData.count를 출력하면 0이 출력된다.bigData.data를 출력하면 참조값인 null이 출력된다. 이 변수는 아직 아무것도 참조하고 있지 않다.bigData.data.value를 출력하면 data의 값이 null이므로 null에 .(dot)을 찍게 되고, 따라서 참조할 곳이 없으므로 NullPointerException 예외가 발생한다.bigData.data.value;
x001.data.value; // bigData는 x001 참조값을 가진다.
null.value; // x001.data는 null 값을 가진다.
NullPointerException // null 값에 .(dot)을 찍으면 예외가 발생한다.
이 문제를 해결하려면 Data 인스턴스를 만들고 BigData.data 멤버 변수에 참조값을 할당하면 된다.
package ref;
public class NullMain4 {
public static void main(String[] args) {
BigData bigData = new BigData(); // x001
bigData.data = new Data(); // x002
System.out.println("bigData.count = " + bigData.count);
System.out.println("bigData.data = " + bigData.data);
System.out.println("bigData.data.value = " + bigData.data.value);
}
}


bigData.data.value;
x001.data.value; // bigData는 x001 참조값을 가진다.
x002.value; // x001.data는 x002 값을 가진다.
0 // 최종 결과
NullPointerException이 발생하면 null 값에 .(dot)을 찍었다고 생각하면 문제를 쉽게 찾을 수 있다.