ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • kotlin null safety
    카테고리 없음 2022. 10. 4. 13:45
    728x90

    코틀린을 시작하면서 신기한 연산자를 정리 했습니다.

    기본적으로 kotlin은 null을 허용하지 않습니다.

    다만 명시적으로 null을 허용할수 있는데요.

    // null 할당시 오류
    var a: String = "abc" // Regular initialization means non-null by default
    a = null // compilation error
    
    // null 명시적 허용 처리
    var b: String? = "abc" // can be set to null
    b = null // ok
    print(b)
    
    // null 인 b의 length에 접근시 오류 발생
    val l = b.length // error: variable 'b' can be null
    

    명시적으로 null을 허용하게 하였다면, 해당 변수의 null 체크는 필수가 되는데요. 코틀린은 이를 어떻게 처리 할까요?

    일반적인 null 체크 문법

    val b: String? = "Kotlin"
    // null 확인 방법 1
    if (b != null && b.length > 0) {
        print("String of length ${b.length}")
    } else {
        print("Empty string")
    }
    
    // null 확인 2
    val l = if (b != null) b.length else -1
    

    안전한 호출

    값을 리턴하는게 아니라면, b?.length 사용하면 오류 없이 호출이 가능합니다. 단, null 일 경우 null 을 리턴합니다.

    val a = "Kotlin"
    val b: String? = null
    println(b?.length)
    println(a?.length) // Unnecessary safe call
    
    // 결과
    null
    6
    

    bob?.department?.head?.name 와 같이 계층구조의 데이터를 확인할때 사용하면 안전하게 호출이 가능합니다.

    다른 예제

    val listWithNulls: List<String?> = listOf("Kotlin", null)
    for (item in listWithNulls) {
        item?.let { println(it) } // prints Kotlin and ignores null
    }
    
    // 결과
    Kotlin
    

    또한 할당을 할때도 null 일 경우 해당 function이 호출 되지 않도록 처리 됩니다.

    // If either `person` or `person.department` is null, the function is not called:
    person?.department?.head = managersPool.getManager()
    

    Elvis operator (엘비스 연산자)

    앞서서 null 체크 문법을 기억하시나요?

    ?: 엘비스 머리모양을 하고 있는 연산자라고 해서 엘비스 연산자라고 불리고 있습니다.

    만약 왼쪽 값이 null 이라면 엘비스 연산자 뒤에 오는 값을 return 합니다.

    // null 체크 
    val l: Int = if (b != null) b.length else -1
    
    // 동일 결과 return
    val l = b?.length ?: -1
    

    null 체크가 참 쉬워지겠지요?

    null 허용된 객체 호출

    null 허용된 객체는 일반적으로 호출이 되지 않습니다.

    ?.(안전한 호출)이나 !!.() 연산자를 이용해서 호출해야 하는데요. !!.의 의미는 null이 아니라는 전제 조건을 설정합니다. 만약 null이면 java.lang.NullPointerException이 발생합니다.

    val b: String? = null
    
    b.length
    error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
    
    b!!.length
    java.lang.NullPointerException
    
    b?.length
    res33: kotlin.Int? = null
    
    // 설사 초기 값을 설정했어도 ?. !!. 없이는 호출이 불가능 합니다.
    val b : String? = "abc"
    
    b.length
    error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
    b.length
    

    안전한 캐스팅

    다른 형으로 캐스팅시 ClassCastException이 발생할 수 있는데요.

    val aInt: Int? = a as? Int
    

    이와 같이 호출을 하면 a가 Int 형이 아니면 null을 리턴 합니다.

    nullable 리스트에 대한 처리

    val nullableList: List<Int?> = listOf(1, 2, null, 4)
    val intList: List<Int> = nullableList.filterNotNull()
    

    filterNotNull을 이용해서 null을 제외한 리스트를 얻을 수 있습니다.

    참고자료

    728x90
Designed by Tistory.