본문 바로가기
Kotlin Language/Kotlin 기본 문법

Kotlin(코틀린) - 널 안전성 (Null-Safety)

by Classic Master 2023. 12. 5.
728x90

널 안전성 (Null Safety) ?

  • null safety(널 안전성)를 강조하는 프로그래밍 언어로, null에 대한 안전한 처리를 지원합니다.  NullPointerException(NPE)과 같은 예외를 방지하고 프로그램의 안정성을 향상시키는 데 도움이 됩니다.
  • 코틀린은 Nullable과 Non-Null 타입으로 프로퍼티를 선언할 수 있으며, 기본적으로 값이 null 아니고 NotNull이다.

 

코틀린에서는 왜 널을 기본값으로 하지 않을까?

  • Java에서 가장 많이 발생하는 오류는 NPE(NullPointerException)입니다.
    코틀린은 코드에서 NPE(NullPointerException)을 제거하기 위해서 기본적으로 허용하지 않습니다.
    허나, null값을 허용하는Nullable 타입으로 프로퍼티를 선언할 수 있다.

Nullable Types (Nullable 타입)

  • 코틀린에서는 기본적으로 모든 변수가 null이 될 수 있는지 여부를 명시적으로 선언합니다. 이를 통해 null 값을 대입할 수 있는 변수를 명시적으로 지정할 수 있습니다.
val nullableString: String? = null
val nonNullableString: String = "Hello, Kotlin!"
  • nullableString은 String?으로 선언되어 있어 null 값을 가질 수 있습니다. 
  • nonNullableString은 String으로 선언되어 있어 null 값을 가질 수 없습니다.

 

Safe Calls (안전한 호출)

  • 안전한 호출을 사용하여 null인지 여부를 확인하고, null이 아닌 경우에만 해당 객체의 메서드나 속성을 호출할 수 있습니다.
val length: Int? = nullableString?.length
  • ?.는 안전한 호출 연산자로, nullableString이 null이면 length에는 null이 할당되고, 그렇지 않은 경우에는 실제 문자열의 길이가 할당됩니다.

 

Elvis Operator (엘비스 연산자)

  • 엘비스 연산자 ?:를 사용하여 null일 때 대체값을 제공할 수 있습니다.
val result: String = nullableString ?: "값"
  • nullableString이 null이라면 result에는 "값"가 할당되고, null이 아닌 경우에는 nullableString의 값이 할당됩니다.

 

!! 연산자 (Not Null Assertion !!)

  • 안전한 호출이 아닌 경우에도 null이 아님이 분명한 경우에 사용할 수 있습니다.
val length: Int = nullableString!!.length
  • !!는 not-null assertion 연산자로, 만약 nullableString이 null이면 NPE가 발생합니다.

 

Safe Cast (안전한 형 변환)

  • 안전한 형 변환을 위해 as?를 사용할 수 있습니다.
val length: Int? = nullableString as? String?.length
  • nullableString이 String이 아니라면 length에는 null이 할당됩니다.

 

널이 가능한 타입 컬렉션 (Collections of Nullable Type)

  • null을 입력할 수 있는 타입의 요소 컬렉션이 있을 때, null이 아닌 요소를 필터링하고 싶다면 filterNotNull을 사용할 수 있습니다:
val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList: List<Int> = nullableList.filterNotNull()

 

 

Null 사용 예제

Nullable 변수와 안전한 호출

  • printLength 함수를 정의하여 입력된 문자열의 길이를 출력하는데, 문자열이 null이면 길이를 null로 설정합니다.
fun printLength(str: String?) {
    val length: Int? = str?.length
    println("Length of the string: $length")
}

fun main() {
    printLength("Kotlin")    // 출력:  6
    printLength(null)        // 출력:  null
}

 

엘비스 연산자 사용

  • getUserEmail 함수를 사용하여 사용자의 이메일을 반환하며, 이메일이 null이면 "Unknown"을 반환합니다.
fun getUserEmail(user: User?): String {
    val email: String = user?.email ?: "Unknown"
    return email
}
data class User(val name: String, val email: String?)

fun main() {
    val user1 = User("Alice", "alice@example.com")
    val user2 = User("Bob", null)

    println(getUserEmail(user1))    // 출력: alice@example.com
    println(getUserEmail(user2))    // 출력: Unknown
}

 

안전한 형 변환

  • printLength 함수를 정의하여 Any 타입의 입력을 문자열로 변환한 후 문자열의 길이를 출력합니다. 만약 형 변환이 실패하면 길이를 null로 설정합니다.
fun printLength(str: Any) {
    val length: Int? = (str as? String)?.length
    println("Length of the string: $length")
}
fun main() {
    printLength("Kotlin")    // 출력: 6
    printLength(42)           // 출력: null (형 변환이 실패하여 null)
}

 

 

참고문서

 코틀린 공식 홈페이지

728x90
반응형