Java

NullPointerException(NPE) 필요한 이유

lee-maru 2020. 10. 20. 22:12

문뜩 백기선 선생님의 수업 (인프런 java 8)Optional에 대한 수업을 듣다가 궁금증이 생겼다.

 

NPE 는 왜 발생하는 걸까?

 

Java NullPointerException API 문서

해석해 보자면 다음과 같다.

 

1. null 인스턴스를 호출할 경우.

2. null object의 필드를 수정하거나, 접근하려고 할 경우

3. null array(배열)에서 길이를 알려고 할 경우

4. null array를 수정하거나 접근하려고 할 경우

5. Throwable 값인 것처럼 null을 던질 경우. (해석을 잘 못하겠음..)

 

 

내가 궁금한 내용은 이거다. 그냥 다른 언어들처럼 사용하려고 해도 null을 던져주면 안되는 걸까?

예를들어 ‘null’을 가진 객체를 출력한다고 가정해보자

 

NullPointerException이 생기는 상황

 

예제1. 다음과 같은 클래스가 있다고 해보자.

public class Patient {	

	private String patientName;	
	private Caregiver caregiver;

	public Patient(String patientName) {		
    	this.patientName = patientName;	
    }

	-Getter, Setter 생략 -
}

public class Caregiver {	

	private String caregiverName;

	-Getter, Setter 생략 -
}

(클래스 생성)

public static void main(String[] args){

	Patient patient = new Patient("seokmin");
    
    Caregiver caregiver = patient.getCaregiver(); // caregiver = null
    
    System.out.println("patient.getPatientName() = " + patient.getPatientName()); // null 출력
    
    System.out.println("patient.getPatientName() = " + caregiver); // null 출력
    
    System.out.println("caregiver.getCaregiverName = " + caregiver.getCaregiverName()); // NPE 발생
    
}

여기서 의문점이 든다. 그냥 caregivernull 이면, null을 출력하듯이,

 

caregiver.getCaregiver 도 null을 출력해주면 되는데, 왜? npe를 발생시킬까..

 

아는 분들은 나의 생각이 답답할 수 있지만,

나는 NPE의 근본적인 이유를 알고 싶었던 것이다. 대부분 NPE 가 발생하면 ‘==’ 비교를 통해서 피하거나,

Optional을 사용하면 된다고 하지만,

왜 npe를 뱉을까 java api에 등록된 글 말고 더 자세히 알려주는 곳이 없었다.

 

결국 한가지 예제를 작성해 보다가 해답을 알게 되었다.

 

Object obj1 = "obj1";

System.out.println( "obj1 =>" + obj1);	// "obj1"출력

System.out.println( "obj1 주소=> "+System.identityHashCode(obj1)); // 1930943285(주소값)

System.out.println( "obj1.method() =>" +obj1.equals("obj1"));  // true

Object obj2 = null;

System.out.println( "obj2 =>" +obj2); // null 출력

System.out.println( "obj1 주소=> " + System.identityHashCode(obj2)); // 0

System.out.println( "obj2.method() =>" +obj2.equals("obj2"));  // NPE 발생

다음의 코드에서 NullPointerException이 발생해야만 하는지 알 수 있었다.

지금까지 getter를 사용하면서 그냥 null.getMethod()를 사용하면 null을 반환하면 되지, 라는 생각부터가 잘못되었다.

null객체에다가 getter 말고도 equals와 같이 다른 메소드를 호출해도 null을 반환하는게 맞을까?

 

equals 의 return 타입은 true / false 인데, null을 반환하는건 잘못된 것이다.

 

그렇기 때문에 NPE를 발생시키는게 맞는 것이다. npe가 당연하게 뜨는게 맞는거지만, npe를 왜 발생시켜야만 하는지에 대해서 알 수 없어서 이렇게 알아봤다, “이런 초보적인걸 모르나?” 할 수 있지만, 그냥 궁금했다.