null
Java에서 `null`은 참조 변수가 어떤 객체도 가리키지 않음을 나타내는 특별한 값이다. `null`은 값이 존재하지 않는,없다는 뜻이다.
기본형(int, double, float)과 달리 참조형(String, int[], Class Object)에는 `null`을 할당할 수 있다.
int a = null; // illgal
double b = null; // illgal
String c = null; // possible
int[] d = null; // possible
클래스 객체에서의 예제
package ref;
public class Data {
int value;
}
package ref;
public class NullMain1 {
public static void main(String[] args) {
Data data = null;
System.out.println("1. data = " + data);
data = new Data();
System.out.println("2. data = " + data);
data = null;
System.out.println("3. data = " + data);
}
}
실행결과
1. data = null
2. data = ref.Data@x001
3. data = null
위 예제는 클래스 `Data` 변수에 null할당과 `new`키워드를 통한 객체 생성에 차이를 보여주는 예제이다.
`Data`타입을 받을 수 있는 참조형 변수 `data`를 만들고 여기에 `null`값을 할당했다. 따라서 `data`변수에는 아직 가리키는 객체가 없다는 뜻이다.
Data data = null;
이후에 새로운 `Data`객체를 생성하여 그 참조값을 `data`변수에 할당했다. 이제 `data`변수가 참조할 객체가 존재한다.
data = new Data();
마지막으로 `data`에 다시 `null`값을 할당했다. 이렇게 하면 `data`변수는 앞서 만든 `Data`인스턴스를 더는 참조하지 않는다.
data = null;
GC - 아무도 참조하지 않는 인스턴스의 최후
아까 예제를 보면 마지막에 `null`을 할당함으로써, 앞서 생성한 `x001``Data`인스터스를 더는 참조하지 않는다. 이렇게 아무도 참조하지 않게 되는 인스턴스는 사용되지 않고 메모리 용량만 차지하게 된다.
과거 C와 같은 프로그래밍 언어에선 개발자 직접 명령어를 사용해서 인스턴스를 메모리에서 제거해야 한다. 만약 실수로 인스턴스 삭제를 누락하면 메모리에 사용하지 않는 객체가 많아져서 메모리 부족 현상이 발생하게된다.
자바는 이런 과정을 자동으로 처리해준다. 아무도 참조하지 않는 인스턴스가 있으면 JVM의 GC(가비지 컬렉션)가 더 이상 사용하지 않는 인스턴스라 판단하고 해당 인스턴스를 자동으로 메모리에서 제거해준다.
객체는 해당 객체를 참조하는 곳이 있으면, JVM이 종료할 때 까지 계속 생존한다. 그런데 중간에 해당 객체를 참조하는
곳이 모두 사라지면 그때 JVM은 필요 없는 객체로 판단다고 GC(가비지 컬렉션)를 사용해서 제거한다.
NullPointerException
참조값이 없는 객체를 찾아갈려고 하면 발생하는 예외가 `NullPointerException`이다. `NullPointerException`은 이름 그래도 `null`을 가리키다(Pointer)인데, 이때 발생하는 예외(Exception)이다.
객체를 참조할 때는 `.`(dot)을 사용한다. `null`를 할당한 객체에 참조를 사용하여 메소드를 호출하거나 필드에 접근하려고하면 `NullPointerException`이 발생하게 된다.
package ref;
public class NullMain2 {
public static void main(String[] args) {
Data data = null;
data.value = 10;// NullPointerException 예외 발생
System.out.println("data = " + data.value);
}
}
NullPointerException 방지 방법
1. null 체크
변수가 `null`인지 확인한 후 작업을 수행한다.
if (str != null) {
System.out.println(str.length());
} else {
System.out.println("String is null");
}
2. Optional 사용 (Java 8 이상)
`Optional` 클래스를 사용하여 `null`을 명시적으로 처리한다.
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
String str = null;
Optional<String> optionalStr = Optional.ofNullable(str);
// null일 경우 기본값 설정
System.out.println(optionalStr.orElse("Default Value"));
}
}
3. 초기화 확인
객체를 초기화한 후 사용하는 것이 중요하다.
String str = "Hello";
System.out.println(str.length()); // 안전
4. @NonNull 애노테이션 활용
Lombok 또는 IDE 플러그인 등을 활용해 null 허용 여부를 명시적으로 지정
NullPointerException과 기본형 타입
- 기본형 타입(int, double, boolean 등)은 null 값을 가질 수 없으므로, NullPointerException과 관련이 없다.
- 하지만 래퍼 클래스(Integer, Double, Boolean 등)는 참조형이기 때문에 null 값을 가질 수 있으며, 이로 인해 NullPointerException이 발생할 수 있다.
Integer value = null;
int num = value; // NullPointerException 발생
참조
'Language > Java' 카테고리의 다른 글
[Java] 접근 제어자와 캡슐화 (0) | 2025.01.10 |
---|---|
[Java] 생성자가 필요한 이유 (0) | 2025.01.09 |
[Java] 변수의 초기화 (0) | 2025.01.07 |
[Java] 기본형 vs 참조형 (0) | 2025.01.04 |
[Java] 클래스와 데이터 (2) | 2024.12.31 |