별의 공부 블로그 🧑🏻‍💻
728x90
728x170

널(Null)

널(Null), 너는 누구니?

코틀린은 변수를 사용할 때 반드시 값이 할당되어 있어야 한다는 원칙이 있다. 만약 값이 할당되지 않은 변수를 사용하면 코틀린에서 오류가 발생한다. 한편 값이 없는 상태는 널(Null) 이라고 부른다.

 

프로그램이 실행되는 도중에 값이 null 인 변수에 접근하려 하면 NPE(NullPointerException) 오류가 발생한다. 변수에 null 할당을 허용하려면 자료형 뒤에 물음표 기호(?)를 명시해야 한다.

 

null을 이용한 변수 검사

  • 코틀린의 변수 선언은 기본적으로 null을 허용하지 않는다.
val a: Int = 30
var b: String = "Hello"

 

  • 다음과 같이 null 가능한 변수들을 선언할 수 있다.
val a: Int? = null
var b: String? = null

 

NPE(NullPointerException)

  • 사용할 수 없는 null 인 변수에 접근하면서 발생하는 예외

 

예제

fun main() {
    var str1: String = "Hello Kotlin"
    str1 = null    // null 을 허용하지 않음. (오류 발생)
    println("str1: $str1")
}

 

  • 다음과 같이 자료형 옆에 물음표 기호(?)를 붙여주면 null 할당을 허용하는 변수를 생성할 수 있다.
fun main() {
    var str2: String? = "Hello Kotlin"
    str1 = null    
    println("str2: $str2")
}
str2: Hello Kotlin

 

null 처리 방법

  • 코틀린에서는 기본적으로 NotNull 이고, Nullable 표현에만 '?'가 사용된다.
fun set(a: String, b: String?) {
    // Do Nothing
}
var temp: String? = null
var size = -1
if (temp != null) {
    size = temp.length
}

// or

var temp: String? = null
var size = if (temp != null) temp.length else -1

 

세이프 콜(Safe-Call)과 non-null 단정 기호 활용

fun main() {
    var str1: String? = "Hello Kotlin"
    str1 = null
    println("str1: $str1 length: ${str1.length}")    // null을 허용하면 length가 실행될 수 없음.

 

다음과 같이 세이프 콜(Safe-Call, ?.)을 사용하면 정상적으로 실행할 수 있다.

fun main() {
    var str1: String? = "Hello Kotlin"
    str1 = null
    println("str1: $str1 length: ${str1?.length}")    // str1을 세이프 콜로 안전하게 호출
str1: null length: null

 

다음과 같이 null 이 아닌 변수를 단정하고 싶으면 non-null 단정 기호(!!.)를 사용 하면 된다. non-null 단정 기호는 null이 아님을 단정하므로 컴파일러가 null 검사 없이 무시한다. 따라서 null 이 할당되어 있을지라도 컴파일은 잘 진행되지만, 실행 중에는 NPE를 발생시킨다. 따라서 되도록이면 사용하지 않는 것이 좋은데 반드시 널이 아니라는게 보장될 때만 사용해야 한다.

println("str1: $str1 length: ${str1!!.length}")    // str1을 non-null 단정 기호로 안전하게 호출

 

조건문을 활용해 null을 허용한 변수 검사하기

  • if else 의 활용
fun main() {
    var str1: String? = "Hello Kotlin"
    str1 = null
    // 조건식을 통해 null 상태 검사
    val len = if (str1 != null) str1.length else -1
    println("str1: $str1 length: ${len}")
}

 

세이프 콜과 엘비스 연산자를 활용해 null을 허용

  • null을 허용한 변수를 조금 더 안전하고 간단하게 사용하려면 세이프 콜 ?.엘비스 연산자 ?: 를 함께 사용하면 된다.
str1?.length ?: -1
// str1이 null이 아닐 경우 str1.length를, null일 경우 -1를 반환한다.
fun main() {
    var str1: String? = "Hello Kotlin"
    str1 = null
    println("str1: $str1 length: ${str1?.length ?: -1}")    // 세이프 콜과 엘비스 연산자 활용
}

 

엘비스 연산자(Elvis Operator)

  • 변수가 null 인지 아닌지 검사하여 null이 아니라면 왼쪽의 식을 그대로 실행하고, null 이라면 오른쪽의 식을 실행한다.
  • ?: 로 표현하며, ?: 의 왼쪽 객체가 non-null 이면 그 객체의 값이 리턴되고, null 이면 ?: 의 오른쪽 값을 리턴한다.
x = f() ?: g()
// f()가 null이 아니면 f()를, null 이면 g()를 변수 x에 할당한다.

 

생각해 보기

Q. 왜 널을 최대한 피해야 할까?

A. NPE(NullPointerException)를 발생시킬 수 있기 때문이다.

 

Q. 변경 불가능한(Immutable) 변수를 적극 활용하는 이유는 무엇일까?

A. 변수가 변경되어 버그를 발생시키는 상황을 예방하기 위해서이다.

 

참고 사이트

 

코틀린 프로그래밍 기본 1

부스트코스 무료 강의

www.boostcourse.org

 

728x90
그리드형(광고전용)
⚠️AdBlock이 감지되었습니다. 원할한 페이지 표시를 위해 AdBlock을 꺼주세요.⚠️
starrykss
starrykss
별의 공부 블로그 🧑🏻‍💻


📖 Contents 📖