이 예제는 코틀린 쿡북을 읽고 정리한 내용입니다.
아래와 같은 클래스가 하나 존재한다고 해보자.
class Person(
val first: String,
val middle: String?,
val last: String,
)
코틀린에는 Nullable(null 을 허용) 이라는 개념이 존재한다.
왜 이런 개념이 필요하지? 라는 의문을 가질 수 있는 사람이 분명 있을 것이기에 간단하게 짚고 넘어가려고 한다.
Nullable 을 도입하는 이유는 Null 로 부터 더 안전해지기 위해서이다.
예를 들어 A 라는 변수에 Null 이 대입될 수 있다고 해보자.
자바같은 경우에는 A 라는 변수에 Null 이 들어갈 수 있다는 것을 런타임에 되서야 알 수 있을 것이다.
그렇게 되면 우리는 NullPointerException 을 맞이하게 된다.
하지만 Kotlin 에서는 A 라는 변수에 Null 값이 들어갈 수 있다는 것을 컴파일 시간에 알 수 있다.
이는 컴파일때부터 NullPointerException 을 방지할 수 있음을 의미한다.
자세한건 아래코드를 한번 보자.
fun test1() {
val name: String
val name2: String?
// 아래와 같이 null 을 할당하면 컴파일이 되지 않음
// name = null
name2 = null
}
위와 같이 ? 를 붙이지 않은 name 변수에는 null 을 할당할 수 없다.
Null 이 허용되지 않는 변수라고 명시적으로 선언해줬기 때문이다.
그와반대로 Null이 허용되는 변수라고 선언해준 name2 의 경우에는 Null 의 대입이 가능하다.
만약 우리가 name2 를 이용한다면 반드시 Null-Check 를 하게 된다.
이로서 Null 값에 대한 처리가 가능한 것이다.
아래 코드를 한번보자
class Person(
val first: String,
val middle: String?,
val last: String,
)
fun test2() {
val p = Person(
first = "North",
middle = null,
last = "West"
)
if (p.middle != null) {
// smart cast!
val middleNameLength = p.middle.length
}
}
Person Class 의 middle 값은 명시적으로 Null 이 허용되는 property 이다.
따라서 우리가 p.middle.length 를 사용하기 위해서는 반드시 Null 체크를 해주어야 한다.
본문에서는 if 문을 통해서 Null-Check 를 진행하고 있다.
만약 위와 같이 if 를 통해 Null-Check 를 하게 되면 아래 스코프에서는 Smart Cast 가 되어 Null 값이 아닌 객체로 사용된다.
되게 편한 기능인데 아마도 IDE가 제공해주는 기능일 것이다. (?)
여하튼 근데 var
로 할경우에는 smart cast 가 되지 않는다.
그 이유는 중간에 값이 바뀔 수도 있다고 판단하기 때문이다.
아래 예시를 한번보자.
fun test3() {
var p = Person(
first = "North",
middle = null,
last = "West"
)
if (p.middle != null) {
// not smart cast! var 를 사용할 경우에는 smart cast 가 되지 않는다.
// val middleNameLength = p.middle!!.length
// 다만 not-null assertion operator 는 NullPointerException 을 유발할 수도 있으므로 ? 연산자를 이용하자
val middleNameLength = p.middle?.length
}
따라서 var 의 경우에는 자신이 코드를 보고 Null 에 대한 안전한 처리를 진행해주면 되는데
예를 들면 위의 경우와 같이 !!(not-null assertion operator) 을 이용해줘도 되고 ? 연산자를 이용해줘도 된다.
다만 !!
의 경우 null 일 경우 NullPointerException 을 마주할 것이다.
내 생각에 코틀린의 장점은 Null-Safety 인데 !! 를 쓰는건 좋은 방향은 아니라고 생각한다.
? 연산자의 경우에는 null 일 경우 null 을 리턴해준다.
위의 경우 엘비스 연산자를 통하면 좀더 안전하게 처리할 수 있는데 바로 아래와 같은 방식으로 말이다.
fun test4() {
var p = Person(
first = "North",
middle = null,
last = "West"
)
if (p.middle != null) {
// not smart cast! var 를 사용할 경우에는 smart cast 가 되지 않는다.
// val middleNameLength = p.middle!!.length
// 다만 not-null assertion operator 는 NullPointerException 을 유발할 수도 있으므로 ? 연산자를 이용하자
val middleNameLength = p.middle?.length ?: 0
}
}
이렇게 할 경우 기본적으로 0
이 리턴되어 좀 더 안전한 처리가 가능하다.
삼항식과 비슷하다고 생각하면 편하다.
Kotlin 은 Null-Safety 하기 위해 많은 기능을 제공한다.
Java 에서는 Optional 을 사용해야 했지만 Kotlin 에서는 그럴필요가 없다.
Nullable 에 대한 개념자체가 언어의 기본 스펙이다.
이를 잘 이용해서 NullPointerException 을 피해보자!
'Kotlin' 카테고리의 다른 글
Kotlin 의 확장함수가 좋은 이유 (0) | 2022.03.18 |
---|---|
Ko-Test Framework 사용해보기 (0) | 2022.01.21 |
[Kotlin Spring] Logger 를 간편하게 (0) | 2021.12.14 |
[Mac] Kotlin 설치 및 CLI 에서 사용하기 (0) | 2021.12.06 |
Kotlin Null 처리 (0) | 2021.11.18 |