참조값 없이 객체를 찾아가면 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)을 찍었다고 생각하면 문제를 쉽게 찾을 수 있다.