밤빵's 개발일지
[TIL]20241006 Nullable과 Non-Nullable 타입: 코틀린의 null 안전성 본문
NPE(NullPointerException)라는 에러는 변수나 객체가 null인 상태에서 메서드를 호출하거나 접근하려고 할 때 발생하는 대표적인 런타임 에러 중 하나다. 자바에서는 null 값을 허용하는 변수와 그렇지 않은 변수를 구분하지 않기 때문에 이 에러를 방지하기 위해 별도의 null 체크를 해야 한다.하지만 코틀린에서는 이러한 문제를 미리 방지할 수 있는 null 안전성 기능을 제공한다.
▶자바에서의 NPE 문제
자바에서는 변수에 null 값을 할당하는 것이 기본적으로 허용된다. 따라서 null이 할당된 변수를 사용할 때 메서드를 호출하거나 필드에 접근하면 NullPointerException이 발생하게 된다.
String name = null;
System.out.println(name.length()); // NPE 발생
→ name에 null을 할당한 후 length() 메서드를 호출하면 런타임 시 NPE가 발생한다. 자바에서 이 문제를 방지하기 위해서는 null 체크를 해야 하는데, 이는 코드가 복잡해지고 실수로 체크를 빠뜨릴 가능성이 있다.
if (name != null) {
System.out.println(name.length());
}
→ null 체크를 추가하여 NPE를 방지할 수 있지만, 모든 코드에서 일일이 null 체크를 하는 것은 번거롭고 실수를 유발할 수 있다. 이러한 문제를 해결하기 위해 코틀린은 더 안전한 null 처리를 위한 기능을 제공한다.
▶코틀린의 Nullable과 Non-Nullable 타입
코틀린에서는 변수에 null을 허용할지 여부를 명시적으로 지정할 수 있다. Non-Nullable 타입은 null을 허용하지 않는 타입이고, Nullable 타입은 null을 허용하는 타입이다. 이를 통해 컴파일 타임에 null 관련 에러를 미리 방지할 수 있다.
▷Non-Nullable 타입
코틀린에서는 기본적으로 모든 변수는 Non-Nullable 타입이다. 변수를 선언할 때 그 변수는 null 값을 가질 수 없다는 것을 의미한다. 만약 null을 할당하려고 하면 컴파일 에러가 발생한다.
var name: String = "John"
name = null // 컴파일 에러: Null을 할당할 수 없음
→ String 타입으로 선언된 변수는 null을 허용하지 않으므로, null을 할당하려고 하면 컴파일 시점에서 오류가 발생한다. 이를 통해 런타임에 NPE가 발생할 가능성을 사전에 차단할 수 있다.
▷Nullable 타입
만약 변수에 null 값을 허용해야 한다면, 타입 뒤에 '?' 기호를 붙여서 Nullable 타입으로 선언해야 한다. Nullable 타입은 null을 허용하며, null 값을 가질 수 있다.
var name: String? = "John" // Nullable 타입 선언
name = null // 가능: null 값을 할당할 수 있음
→ String? 타입은 Nullable 타입으로, null 값을 가질 수 있다. 하지만 Nullable 타입의 변수는 바로 메서드를 호출할 수 없으며, 이를 안전하게 사용하기 위해 다양한 방법을 제공한다.
▶Nullable 타입 안전하게 사용하기
코틀린에서는 Nullable 타입을 안전하게 사용할 수 있도록 여러 가지 방법을 제공한다.
▷안전 호출 연산자(?.)
안전 호출 연산자 '?.'를 사용하면, 해당 변수가 null인 경우 메서드를 호출하지 않고 null을 반환하게 된다. 이를 통해 NPE를 방지할 수 있다.
var name: String? = "John"
println(name?.length) // name이 null이 아니면 length 호출, null이면 null 반환
→ 만약 name이 null이면 name?.length는 null을 반환하고, 그렇지 않으면 정상적으로 length() 메서드를 호출한다.
▷엘비스 연산자(?:)
엘비스 연산자 '?:'는 Nullable 값이 null일 때, 기본값을 지정할 수 있도록 한다. 이를 통해 null인 경우에 대비한 값을 간단하게 지정할 수 있다.
var name: String? = null
val length = name?.length ?: 0 // name이 null이면 기본값 0을 사용
println(length) // 출력: 0
→ name이 null이므로 length에는 기본값인 0이 할당된다. 엘비스 연산자를 사용하면 null에 대한 대체 값을 쉽게 설정할 수 있다.
▷Not-Null 단언 연산자(!!)
'!!' 연산자는 변수의 값이 null이 아님을 개발자가 확신할 때 사용하는 연산자이다. 만약 null일 경우, NPE가 발생하므로 이 연산자는 신중하게 사용해야 한다.
var name: String? = "John"
println(name!!.length) // name이 null이 아니므로 length 호출
→ 이 연산자는 nullable 변수를 Non-Nullable 변수처럼 취급하게 해주지만, null이 들어오는 경우 예외가 발생하기 때문에 꼭 필요한 경우에만 사용해야 한다.
▶Nullable과 Non-Nullable의 사용 예시
자바에서 흔히 사용하는 null 체크를 코틀린에서는 아래와 같이 처리할 수 있다.
▷자바 코드
String name = null;
if (name != null) {
System.out.println(name.length());
} else {
System.out.println("name이 null입니다");
}
▷코틀린 코드
var name: String? = null
println(name?.length ?: "name이 null입니다")
→ 코틀린은 더 간결하고 명확하게 null 처리를 할 수 있다는 장점이 있다.
▶코틀린의 null 안전성 기능의 장점
→ 컴파일 타임에 오류 방지:
Non-Nullable 타입과 Nullable 타입을 명확히 구분하여 컴파일 타임에 null로 인한 오류를 방지할 수 있다.
→ 간결한 코드:
안전 호출 연산자와 엘비스 연산자를 통해 null 체크를 간단하게 처리할 수 있다.
→ NPE 방지:
코틀린의 null 안전성 기능 덕분에 자바에서 흔히 발생하는 NPE 문제를 효과적으로 해결할 수 있다.
코틀린의 null 안전성 기능을 통해 자바에서 자주 발생하는 NPE 문제를 효과적으로 해결할 수 있다. Non-Nullable과 Nullable 타입을 명확히 구분하여 null에 대한 처리를 컴파일 시점에서 안전하게 처리할 수 있으며 특히, 안전 호출 연산자 ?., 엘비스 연산자 ?: 등을 사용하여 간결하게 null 처리를 할 수 있다.
'Kotlin' 카테고리의 다른 글
[TIL]20241008 코틀린의 함수 선언 & 사용법 (0) | 2024.10.08 |
---|---|
[TIL]20241007 Safe Call(?.), Elvis 연산자(?:), Not-null Assertion(!!) 활용 (0) | 2024.10.07 |
[TIL]20241005 자바와 코틀린의 변수 선언 방식 차이 (1) | 2024.10.05 |
[TIL]20241004 var과 val 의 차이? (0) | 2024.10.04 |
[TIL]20241002 Coroutines② (0) | 2024.10.02 |