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. 변수가 변경되어 버그를 발생시키는 상황을 예방하기 위해서이다.
참고 사이트
728x90
그리드형(광고전용)
'Programming > Kotlin' 카테고리의 다른 글
[Kotlin] 검사와 자료형 변환 (0) | 2022.09.21 |
---|---|
[Kotlin] 자료형과 변수 (0) | 2022.08.27 |
[Kotlin] InteliJ IDEA 살펴보기 & main() 함수 (0) | 2022.08.26 |
[Kotlin] 자바 JDK 설치하기 / 환경 변수 설정하기 (0) | 2022.08.26 |
[Kotlin] 코틀린의 개요 (0) | 2022.08.24 |
[Kotlin] 코틀린 한 눈에 알아보기 (0) | 2022.08.21 |
보일러플레이트(Boilerplate) (0) | 2021.04.05 |
함수에서 다양한 인자의 개수를 전달받기 (vararg 키워드) (0) | 2021.03.15 |