엔지니어 규의 IT 프로그래밍 다이어리

[Kotlin] 21. Null 값을 처리하는 방법, 변수가 동일한지 확인하는 방법(난이도 : ★★★) 본문

프로그래밍 언어/코틀린

[Kotlin] 21. Null 값을 처리하는 방법, 변수가 동일한지 확인하는 방법(난이도 : ★★★)

엔지니어 규 2022. 5. 29. 16:04
728x90

Null 값을 처리하는 방법

 

우리는 코틀린에서 nullable 변수를 만들어 객체가 들어있지 않은 Null 상태를 만들 수 있다.

fun main(){

    var sample : String? = null
    if (sample != null){
        println(sample.toUpperCase())
    }

}

하지만 null 상태로 속성이나 함수를 쓰려고 하면 null pointer exception이 발생하기 때문에 

nullable 변수를 사용할때는 null check 없이 코드가 컴파일되지 않는다. 

null check 을 하기위해 일일히 if문으로 조건을 체크하는 대신 편리한 방법을 제공한다.

 

?. -> null safe operator

?: -> elvis operator

!!. -> non-null assertion operator

 

null safe 연산자 : 참조연산자를 실행하기 전에 먼저 객체가 null 인지 확인부터 하고, 객체가 null 이라면 뒤따라오는 구문을  실행 안함.

(sample?.toUppercase() 에서 toUppercase()를 실행하지 않는다.)

 

elvise 연산자 : 객체가 null 이 아니라면 그대로 사용하지만, null 이라면 연산자 우측의 객체로 대체된다.

(sample?: "default" 에서 sample 이 null 이니까 "default" 를 쓰게된다.)

 

non-null assumption 연산자 : 참조연산자를 사용할때 null 여부를 컴파일시 확인하지 않도록 하여,

런타임시 null pointer exception 이 나도록 의도적으로 방치하는 연산자 이다. 

 

아래 코드를 통해 확인해보자

fun main(){

    var a : String? = null

    println(a?.toUpperCase())  //null
    println(a?:"default".toUpperCase()) //DEFAULT
    println(a!!.toUpperCase())  // NullPointerException error 발생

}

 

null safe 연산자는 scope 함수와 사용하면 더욱 편리하다.

아래의 코드를 통해 알아보자.

fun main(){

    var a : String? = null

    a?.run{
        println(toUpperCase())  // 실행 X
        println(toLowerCase()) // 실행 X
    }

    var b : String? = "Kotlin Exam"

    b?.run{
        println(toUpperCase())  //KOTLIN EXAM
        println(toLowerCase()) // kotlin exam
    }

}

 

run 함수는 null을 체크하기 위해 if 문 대신 사용하면 상당히 편리한 기능이므로 꼭 알아두자.

 

변수가 동일한지 확인하는 방법

 

동일성에는 내용의 동일성객체의 동일성이 있다.

 

 

내용의 동일성 은 메모리상에 서로 다른 곳에 할당된 객체라 해도 그 내용이 같으면 동일하다고 판단한다.

 

 

객체의 동일성은 서로 다른 변수가 메모리상에 같은 객체를 가리키고 있을때만 동일하다고 판단한다.

 

 

내용의 동일성을 판단하는 연산자는  a==b 처럼 "==" 을 사용하며,

객체의 동일성을 판단하는 연산자는 a===b  처럼 "===" 을 사용한다.

 

이중 내용의 동일성은 자동으로 판단되는 것이 아닌 코틀린의 모든 클래스가 내부적으로 상속받는

"Any"라는 최상위 클래스의 equals()함수가 반환하는 boolean 값으로 판단하게 된다.

 

기본 자료형에는 자료형의 특징에 따라 equals()함수가 이미 구현되어 있지만 우리가 커스텀 class 를 만들때는

open fun equals(other : Any?) : Boolean 와 같은 equals 를 상속받아 동일성을 확인해주는 구문을 별도로 구현한다.

 

 

아래의 코드를 보자.

fun main(){

    var a = Product("콜라",1000)
    var b = Product("콜라",1000)
    var c = a
    var d= Product("사이다",1000)

    println(a == b)  //true
    println(a === b) //false

    println(a == c) //true
    println(a === c) //true

    println(a == d) // false
    println(a === d) //false


}
class Product(val name: String, val price: Int){
    override fun equals(other: Any?): Boolean {
        if (other is Product){
            return other.name == name && other.price == price
        } else {
            return false
        }
    }
}

위 코드를 출력해보면

 

a 와 b는 내용은 같지만 객체는 서로 별개임을 알수있고,

a와 c는 내용과 객체 모두 일치하며

a와 d는 내용과 객체 모두 불일치 한다는 사실을 알 수 있다.

 

 

Null 처리와 동일성의 확인은 프로그램 작성 도중  빈번하게 사용하는 기능이다.

728x90
Comments