프로그램의 수많은 오류 중 대표적인 오류로 NPE(Null Pointer Exception)가 있다.
코틀린은 Null 처리를 위해 다양한 방법을 제공한다.
var name : String?
위와 같이 자료형 뒤에 ?를 붙이면 널허용 자료형이 된다.(wrapping)
원래의 자료형으로 언래핑하려면 변수명!!을 해주면 된다.
name!!
!!은 널이 아님을 명시해주는 표시이다.
그럼 다음을 보자.
<널허용 자료형 예시>
var name :String? = null
val nameLength :Int = name.length // 오류 발생!
위의 코드를 작성하면 오류가 발생한다. name에 널허용이 되어있는한 length에 접근할 수 없다.
var name :String? = "Kim"
val nameLength :Int = name.length // 오류 발생!
name에 "Kim"을 할당해주면? 그래도 위의 코드는 오류가 발생한다.
어쨌든 name은 여전히 널허용이기 때문에 legnth에 접근할 수 없기 때문이다.
< !! 사용 예시 >
var name :String? = "Kim"
val nameLength :Int = name!!.length // 정상 실행!
위의 코드는 실행 시 오류가 발생하지 않는다. name이 처음엔 널허용이었지만
아랫줄에 !!을 붙여줌으로써 이제 널이 아님을 명시해주었기 때문이다.
var name :String? = null
val nameLength :Int = name!!.length // 컴파일 이후 오류 발생!
그럼 name에 null을 할당하면? 위의 코드는 작성 시에는 오류가 발생하지 않는다.
!! 후에 length에 접근하는 건 문제가 없기 때문이다.
하지만 컴파일 후 실제로 프로그램을 실행시키면 오류가 발생한다.
name에 실제로 할당된 값이 널이므로 length에 접근할 수 없기 때문이다. 그럼 어떻게 오류를 피할 수 있을까?
?.으로 Null 대처하기
var name :String? = null
val nameLength :Int = name?.length // 오류 발생! name?.length은 널허용이기 때문이다.
val nameLength :Int? = name?.length // 정상 실행! nameLength을 널허용자료형으로 선언해주어야 한다.
val nameLength = name?.length // 정상 실행! 등호 우측의 자료형을 통해 예측가능하므로 nameLength의 자료형은 생략 가능
위와 같이 name?.length을 적어주면 된다. name이 null이 아닐 때만 length에 접근하고 null이면 그대로 null을 반환한다. 따라서 위의 코드에서 nameLength에는 null이 할당된다.
?. + ?: 으로 Null에 대해 좀 더 유연하게 대처하기
var name :String? = null
val nameLength :Int = name?.length ?: -1
println("nameLength : $nameLength")
>> nameLength : -1
name?.length ?: -1
와 같이 코드를 작성하면 name을 검사하여 null이 아니면 length를 반환하고 null이면 ?: 우측을 반환하겠다는 의미이다.
따라서 위의 코드를 실행하고 버튼을 클릭하면 name은 null이므로 nameLength에는 -1이 할당된다.
댓글