티스토리 뷰
Java를 포함한 많은 프로그래밍 언어에서 가장 대표적인 오류중 하나는 참조값이 없는 멤버에 액세스하면 널 참조 예외가 발생한다는 것입니다. Java에서 이것은 NullPointerException 또는 NPE와 동일합니다.
이 Null을 처음 도입한 Tony Hoare
가 다음과 같이 말했다고 합니다.
'I call it my billion-dollar mistake.'
코틀린에서는 기본적으로 변수를 정의할때 Null을 허용하지 않도록 개발되었고, null을 허용하더라도 컴파일할때 null 참조할 가능성을 다 체크해주어 안전하게 프로그램을 짤 수 있는 장점이 있습니다.(제 개인적으로 코틀린의 가장 큰 장점입니다.)
Null을 허용하지 않는 변수 vs Null을 허용하는 변수
fun test(a: String, b: String?) {
// Do noting
}
다음 코드에서 차이를 명확히 알 수 있습니다. 간단합니다. ?
가 붙었느냐의 차이입니다.?
가 붙으면 Null 참조할 수도 있다는 의미입니다.?
가 없으면 null 참조를 안 하는 변수 라는 의미이며 이 변수를 null 체크 안해도 됩니다.
String name = null;
int size = -1;
if (name != null) {
size = name.length();
}
이와 같은 Java에서의 null 체크를
var name: String? = null
val size = name?.length ?: 0
코틀린에서는 이렇게 줄여쓸 수 있습니다.?
사용은 바로 아래에 설명하겠습니다.
Safe Calls
코틀린에서는 Null 참조할 수 있는 변수에 대해 ?.
를 붙여서 Null이 아닐경우만 함수를 호출할 수 있습니다.
// 만약 null을 참조하는 변수라면
val name: String? = null
// 아래와 같이 ?.을 사용하여 null일 경우 null객체로부터 length함수 호출하는걸 피할 수 있습니다.
val size = name?.length
위의 결과는 name이 null이므로 length 함수는 호출 안하고 size에는 null이 담기게 됩니다.
이 장점을 응용하면 중첩된 클래스 안에 내부 변수를 참조할 때 간결하게 코드를 짤 수 있습니다.
Java에서는 이와 같이 짜는걸 많이 경험한 분들이 계실겁니다. 실제 현업에서 비즈니스가 복잡해지며 이런 케이스가 빈번하죠.
// null check
if (school != null && school.class != null && school.class.name != null) {
return school.class.name.age;
}
return null;
반면 Kotlin에서는 한 줄로 짤 수 있습니다.
// safe calls chaining
return school?.class?.name?.age
Null 참조를 하면 Exception을 발생시키고 싶은 경우
시스템 구현하며 어떤 변수에는 분명 Null 참조할 리가 없지만 어쩔 수 없이 NUll 참조 가능한 변수를 선언해야 하는 경우가 있습니다.
저는 주로 API 호출하고 응답 메시지를 처리하는 상황에 API 응답메시지에 Null이 아닐 경우에 사용하는데 코틀린에서는 !!를 사용하면 Null일 경우 NPE이 발생하게 하고 그다음 함수 호출을 구현할 수 있습니다.
var name: String? = null
val size = name!!.length
이 코드는 NPE이 발생합니다.
형변환할 때 발생할 수 있는 에러 예방
코틀린에서는 TypeCastException도 ?
를 사용하여 안전하게 피할 수 있습니다.
val itemId: String? = ""
// 이 방법은 TypeCastException 발생
val itemIdAsInt: Int? = itemId.toInt
// 이 경우 TypeCastException 회피, null이 저장
val itemIdAsInt: Int? = itemId as? Int
// null이 아닌 0을 저장
val itemIdAsInt: Int? = itemId as? Int ?: 0
filterNotNull 로 Null인 Element를 제외
만약 Null 이 포함된 리스트를 다룰 경우에 새로운 list를 생성하고 Null 참조 불가능한 변수를 생성해서 코드를 더 편하게 짤 수 있습니다.
val nullContainList: List\[Int?\] = listOf(1, 2, null, 4)
for (i in nullableList) {
// Null 참조 가능한 변수로 선언하면 아래처럼 해당 변수를 사용할 때마다 null일 경우를 염두하여 개발해야합니다
nullContainList?.let {print("${i}")
}
// 아래와 같이 Null 참조 안하는 변수 Int List로 선언하면 Null 일 가능성을 생각안 해도 됩니다.
val intList: List = nullableList.filterNotNull()
for (i in intList) {
print("${i} ")
}
이와 같이 코틀린에는 기본적으로 Null 참조 안하는 변수를 사용하여 NPE을 예방할 수 있으며 부득이하게 Null참조 가능한 변수를 사용한다해도 안전하고 간결하게 Null 체크 할 수 있습니다.
코틀린은 NPE을 예방할 수 있는 좋은 언어입니다.
'Computer Language > Kotlin' 카테고리의 다른 글
[Kotlin] How to convert List to an array in Kotlin? (0) | 2019.09.03 |
---|---|
[TroubleShooting] CoroutineContext version up issue (0) | 2019.08.30 |
[TroubleShooting] Kotlin not configured in IntelliJ (0) | 2019.08.27 |
[Kotlin] How to use Null safely (0) | 2019.08.26 |