학습
Kotlin null 안전성
Kotlin null 안전성 — 초급
null 안전성
1. 도입 (왜 배워야 하는가)
Kotlin 언어에서 null 안전성은 매우 중요한 개념입니다. 프로그래밍을 하면서 null 값은 자주 발생하는 문제인데, 이를 처리하지 않으면 NullPointerException이라는 오류가 발생할 수 있습니다. 이는 프로그램의 크래시를 유발하거나, 예기치 않은 동작을 초래할 수 있습니다. 특히 실무에서 다수의 사용자가 동시에 접속하는 어플리케이션에서는 이러한 오류가 치명적일 수 있습니다.
예를 들어, 쇼핑몰 애플리케이션에서 사용자가 장바구니에 상품을 추가하는 기능을 구현한다고 가정해보겠습니다. 만약 장바구니 객체가 null인 상태에서 상품을 추가하려고 할 경우, 런타임 오류가 발생하여 사용자에게 큰 불편을 초래할 수 있습니다. Kotlin의 null 안전성을 이해하고 활용하는 것은 이러한 문제를 예방하는 데 필수적입니다.
2. 핵심 개념 설명
Kotlin에서는 null 값을 안전하게 처리하기 위한 여러 가지 방법이 제공됩니다. 주요 개념은 다음과 같습니다:
| 용어 | 설명 |
|---|---|
| Nullable 타입 | 타입 뒤에 ?를 붙여 null 값을 가질 수 있는 타입을 의미합니다. |
| Non-nullable 타입 | 기본적으로 null 값을 가질 수 없는 타입입니다. |
| Safe call | ?. 연산자를 사용하여 null이 아닐 경우에만 메소드를 호출하는 방법입니다. |
| Elvis 연산자 | ?:를 사용하여 null일 경우 대체 값을 지정하는 방법입니다. |
실생활 비유로 설명하자면, Nullable 타입은 '열쇠가 있을 수도 있고 없을 수도 있는 집'과 같고, Non-nullable 타입은 '열쇠가 반드시 있는 집'으로 비유할 수 있습니다. 안전한 호출(Safe call)은 문을 열 수 있을 때만 들어가고, Elvis 연산자는 문이 잠겨 있을 때 대체 방법을 제공하는 것과 같습니다.
3. 기본 코드 예제
가장 기본적인 null 안전성 사용법을 보여주는 코드는 다음과 같습니다.
fun main() {
var name: String? = null // Nullable 타입
println(name?.length) // Safe call을 이용한 호출
name = "Kotlin"
println(name?.length) // Safe call을 이용한 호출
}
실행 결과
null
6
코드 한 줄씩 동작 설명
var name: String? = null-name변수를 Nullable 타입으로 선언하고, 처음에는 null로 초기화합니다.println(name?.length)-name이 null이므로, 길이를 출력하지 않고null을 출력합니다.name = "Kotlin"-name변수에 "Kotlin"이라는 문자열을 할당합니다.println(name?.length)-name이 null이 아니므로, "Kotlin"의 길이인 6이 출력됩니다.- Kotlin의 null 안전성은 NullPointerException을 방지하는 데 매우 중요합니다.
- Nullable 타입은
?, Non-nullable 타입은 기본적으로 null을 허용하지 않습니다. - Safe call(
?.)과 Elvis 연산자(?:)를 활용하여 안전하게 null을 처리할 수 있습니다. - 다음에 학습하면 좋은 주제는 "Kotlin의 고차 함수"입니다. 이를 통해 더욱 유연하고 강력한 코드를 작성할 수 있습니다.
4. 실전 활용 예제
예제 1: 장바구니 구현
쇼핑몰에서 장바구니를 구현할 때, 사용자가 장바구니에 상품을 추가하는 상황을 생각해보겠습니다.
class Cart {
var items: MutableList<String>? = null // 초기 null
fun addItem(item: String) {
items?.add(item) ?: run {
items = mutableListOf(item) // items가 null이면 새로 생성
}
}
}
fun main() {
val cart = Cart()
cart.addItem("사과")
cart.addItem("바나나")
println(cart.items) // [사과, 바나나]
}
상황 설명: 사용자가 처음 장바구니에 "사과"를 추가할 때, items가 null이므로 새로운 리스트를 생성하여 해당 아이템을 추가합니다.
예제 2: 사용자 정보 조회
사용자 정보를 조회하는 API에서, 사용자의 이메일이 null일 경우 기본 이메일을 설정하는 예제입니다.
data class User(val email: String?)
fun getUserEmail(user: User): String {
return user.email ?: "기본 이메일@도메인.com" // Elvis 연산자 사용
}
fun main() {
val userWithNullEmail = User(null)
println(getUserEmail(userWithNullEmail)) // 기본 이메일 출력
}
상황 설명: 사용자의 이메일이 null일 경우, 기본 이메일을 반환하여 시스템의 일관성을 유지합니다.
5. 흔한 실수와 주의사항
실수 1: Nullable 타입을 Non-nullable로 사용하기
var name: String? = null
println(name.length) // 오류 발생: NullPointerException
올바른 코드
println(name?.length) // 안전하게 호출
실수 2: Elvis 연산자를 사용하지 않기
var email: String? = null
println(email) // null 출력
올바른 코드
println(email ?: "기본 이메일@도메인.com") // 기본 이메일 출력