JAVA

참조_NullPointerException

고민말고생각하는사람 2024. 1. 13. 15:32

앞서 null 에 대해 학습할 때 nul 은 '참조 대상'이 없음을 의미한다고 했다.

 

택배 예시와 같이 참조값을 입력할 수 없거나 미루고 싶을 때 null 을 넣으면 된다고 했다.

 

보내는 주체 - 나

보내는 물건 - 노트북

받는 주체 - 삼촌

삼촌 주소 - null

 

그래서, 우리는 삼촌의 주소를 몰라도 택배 발송에 필요한 정보, 물건 등을 미리 챙겨놔도 전혀 문제가 되지 않는다.

 

그. 러. 나

보내는 주체 - 나

보내는 물건 - 노트북

받는 주체 - 삼촌

삼촌 주소 - null

이걸 들고 우체국 창구로 가면 어떻게 된다?

창구 : ?? 받으시는 분 주소가 없는데요? 

 

그렇다. 못 보낸다. 창구 직원이 ??? 를 띄우며 보낼 수 없다고 한다.

보낼 주소가 없는데 보내려고 한다.

 

이런 상황에서 발생하는 것이 바로 Null Pointer Exception 이다.

 

주소가 없는데 받으려고 한다? 이럴 때도 Null Pointer Exception  이다. 

public static void main(String[] args) {
    Data data = null;
    data.value = 10;	// 사실상 null.value -> null을 가리킴Point으로써 예외 발생. NullPointerException
}

data에 할당된 주소값은 없다. 즉 참조하고 있는 인스턴스가 없다. 

 

참조하는 객체가 없는데 접근을 시도한다? 당연히 못한다. 없는데 어떻게 접근함?

 

 

Data 는 Data 타입 인스턴스의 주소값을 담기 위한 변수로 Data 자체는 아니니 착각하지 말자.

인스턴스는 new생성자() 를 통해 생성되며, 인스턴스는 특정 메모리 영역에 저장되고, 이 때 반환된 주소 값을 타입이 맞는 참조형 변수에 넣는 것이다. 헷갈리지 말자.

 

복습용 예시

public static void main(String[] args) {
        BigData bigData = new BigData();
        System.out.println("bigData.count = " + bigData.count); // 0 이 나올 것이다.
        System.out.println("bigData.data = " + bigData.data);   // null 이 나올 것이다.
        System.out.println("bigData.data.value = " + bigData.data.value);   // NullPointerException 이 터질 것이다.
    }

 

1. BigData 클래스의 인스턴스를 생성했다. 이 때, 멤버 변수는 자동으로 초기화 된다.

2. 초기화가 진행될 때, 기본형은 숫자 = 0, boolean = false 등으로 초기화 된다고 했다. 참조형 = null 로 초기화 된다.

3. bigData 인스턴스는 참조형 변수 data 를 멤버형 변수로 갖는다. 그러나, data = null 로 초기화 돼 있다.

4. bigData 에 있는 data(=null).value 에 접근 하려고 하므로, NullPointerException 이 터진다.

 

해결 방법

NullPointerException 문제를 해결하기 위해선 어떻게 해야 할까?

참조형 변수 data 에 객체 주소를 넣어 초기화 해주면 된다.

 

초기화 방법

1. 외부에서 접근해서 초기화

bigData.data = new Data();

2, 인스턴스 생성자를 통한 초기화

Data data = new Data();
BigData bigData = new BigData(data);

생성자에 해서 쬐끔 더 자세하게 나중에 더 파보자.