IMCAT.DEV
로그인 가입
Kotlin 입문 자료구조

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

코드 한 줄씩 동작 설명

  1. var name: String? = null - name 변수를 Nullable 타입으로 선언하고, 처음에는 null로 초기화합니다.
  2. println(name?.length) - name이 null이므로, 길이를 출력하지 않고 null을 출력합니다.
  3. name = "Kotlin" - name 변수에 "Kotlin"이라는 문자열을 할당합니다.
  4. println(name?.length) - name이 null이 아니므로, "Kotlin"의 길이인 6이 출력됩니다.
  5. 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") // 기본 이메일 출력

    6. 정리

    • Kotlin의 null 안전성은 NullPointerException을 방지하는 데 매우 중요합니다.
    • Nullable 타입은 ?, Non-nullable 타입은 기본적으로 null을 허용하지 않습니다.
    • Safe call(?.)과 Elvis 연산자(?:)를 활용하여 안전하게 null을 처리할 수 있습니다.
    • 다음에 학습하면 좋은 주제는 "Kotlin의 고차 함수"입니다. 이를 통해 더욱 유연하고 강력한 코드를 작성할 수 있습니다.