본문 바로가기
JAVA/[JAVA] 바구니

java.lang.NullPointerException 오류1

by oncerun 2020. 3. 3.
반응형

java를 사용하는 프로그래머라면 NPE의 늪에서 빠져나올 수가 없다고 한다. 나 또한 공부를 하는 과정에서 튀어나오는

저 오류때문에 골머리를 앓고 있다. 그래서 서칭을 해보니 먼저 NULL에 대해서 자세히 알 필요가 있다고 생각하고 NULL에 대해 정리를 해보겠다. 

 

NULL.

1) null 은 public, static 이나 final과 같은 Java의 키워드입니다. 컴파일러가 대소문자를 구분하기 때문에 null을 Null이나 NULL로 쓰면 에러를 보게 될 것입니다.  (하지만 최근에는 IDE가 전부 수정해준다.)

 

2) null이란 아무것도 없음을 의미합니다. (0 또는 공백 : "")


3) 모든 primitive 자료형이 기본 값을 가지고 있는 것처럼(if int 는 0, boolean 은 false) null 은 모든 참조형 자료형의 기본값입니다. 당신이 boolean 형의 변수를 생성하면 자동적으로 false 가 들어가는 것과 같이  Java의 참조형 변수는 기본으로 null 이 들어갑니다.  이는 컴파일러가 변수 초기화 에러를 생성하지 않는 한, 모든 변수에 해당합니다. 

 

4) null은 유효한 객체 인스턴스가 아니므로 할당 되는 메모리가 없습니다.

5) null 은 Object 도 일종의 자료형도 아닙니다. 단지 모든 참조형 변수에할당될 수 있는 특수한 변수일이다.

null에게도 형 변환이 가능하다. (ex: String myStr = (string) null;)

 

6) null은 primitive 자료형에게 할당할 수 없습니다.

int i = null; , double j = null; data k = null; float fl = null;, boolean bl = null; 전부 형 변환 오류가 발생합니다. 

 

7) null 은 ==,!= 연산자의 대상이 될 수 있지만, 다른 연산자의 대상은 될 수 없습니다.

String str = null; 

null == null :true;

 null >=(>, <, <= 마찬가지) str : x

 


예외 발생상황 

 

참조형 변수를 선언하면 객체의 포인터가 생성됩니다. 즉, 참조형 변수는 객체의 주소 (참조값)을 저장합니다. 프리티 미트 타입 (기본 타입)인 int 타입의 변수를 다음과 같이 선언한다고 가정해보면:

int x;

x = 10;

 

이 예제의 첫 번째 명령문에서 변수 x는 int 타입으로 선언되어, 자바는 이 변수의 값을 0으로 초기화합니다 (단, 변수 x가 클래스의 필드로 정의되었을 때).

그리고 두 번째 명령문과 같이 해당 변수 x에 10이라는 값을 대입 연산자를 사용하여 할당하면, 변수 이름 x가 가리키는 메모리 위치에 10이라는 값이 쓰입니다.

 

그러나 참조형 타입의 변수를 선언할 때는 다르게 처리됩니다.

 

다음의 코드를 살펴보면:

Integer num;  // num == null

num = new Integer(10);

 

첫 번째 명령문에서 num이라는 이름으로 선언된 변수는 기본값을 저장하지 않습니다.

대신, Integer라는 이름의 타입은 래퍼 클래스로서, 참조형 타입이므로 해당 변수는 주소 (참조값)을 저장합니다.

첫 번째 명령문은 아직 어떤 것을 참조하라고 정의하지 않았기 때문에 자바는 그 변수를 null로 초기화합니다 (단, 변수 num이 클래스의 필드로 정의되었을 때). 이것은 "나는 아무것도 참조하지 않아"라는 의미입니다.

 

두 번째 명령문은 new라는 키워드를 사용해서 Integer 클래스 객체를 생성하고 해당 객체의 주소 (참조값을) num이라는 변수에 저장합니다.

이렇게 객체를 생성하고 객체의 참조값을 저장한 변수를 사용해서 해당 객체에 접근할 수 있습니다. 이때. 연산자를 사용합니다.

 

만약 참조형 타입의 변수를 선언하고 객체를 생성하지 않으면 (즉, 객체의 참조값을 해당 변수에 저장하지 않으면) Exception이 발생됩니다.

즉, 객체가 생성되기 전에 num 변수를 사용해서 해당 클래스의 객체를 접근하고자 하면 NullPointerException이 발생됩니다.

이러한 경우 대부분 컴파일러가 해당 문제를 인식해서 경로 메시지로 알려줄 것입니다. "num 변수가 아직 초기화되지 않았어"라고요.

 

아래와 같은 메서드에 대해서,

public void doSomething(Integer num) {

// do something to num

}

다음과 같이 호출한다면,

doSomething(null);

num 변수의 값은 null이 됩니다. 이러한 null 값을 가지는 num 변수를 사용해서 객체의 필드 혹은 메소드에 접근하고자 한다면 NullPointerException이 발생하게 되는 것입니다. 이와 같은 exception이 발생되지 않게 하는 최선의 방법은 다음과 같이 참조형 변수를 사용하기 전에 null 값을 저장하고 있는지를 체크하는 것입니다




 

반응형

댓글