코틀린(Kotlin)

코틀린(kotlin) : Null Safety 널 세이프티

알통몬_ 2018. 2. 8. 14:30
반응형


공감 및 댓글은 포스팅 하는데

 아주아주 큰 힘이 됩니다!!

포스팅 내용이 찾아주신 분들께 

도움이 되길 바라며

더 깔끔하고 좋은 포스팅을 

만들어 나가겠습니다^^

 


이번 포스팅에서는 코틀린의 Null Safety 에 대해 공부합니다.


Null Safety

코틀린의 타입 시스템은 코드에서 null 참조가 발생하는 위험을 없애는 데에 

목적이 있습니다.  The Billion Dollar Mistake 라고도 불립니다.


자바를 포함한 많은 프로그래밍 언어에서 가장 일반적인 함정 중 하나는

null 참조 멤버에 접근하면 null 참조 예외가 발생한다는 것입니다.

자바에서 NullPointerException, 줄여서 NPE 와 동일합니다.


코틀린의 타입 시스템은 코드로부터 NPE를 없애는 데에 목적이 있습니다.


NPE가 발생하는 유일한 원인은 아래와 같습니다.

- throw NullPointerException()을 호출했을 때

- 아래에서 설명할 !! 연산자를 사용했을 때

- 초기화와 관련된 일부 데이터의 불일치, 아래와 같은 경우

1. 생성자에서 사용할 수 있는 초기화되지 않은 항목이 어딘가에서 사용될 때

2. 수퍼 클래스 생성자가 파생 클래스의 구현에서 

초기화되지 않은 상태를 사용하는 open 멤버를 호출할 때

- 자바 상호운용:

1. 플랫폼 타입의 null 참조로 멤버에 엑세스하려고 할 때

2. 옳바르지 않은 Null 허용을 가진 Java 상호 운용에 사용되는 일반적인 유형

코틀린의 MutableList<String>에 자바 null 을 추가할 수 있습니다.

때문에 MutableList<String?> 사용해야 합니다.

3. 기타 자바코드로 인한 이슈


코틀린에서 타입 시스템은 nullable 참조와 non-null 참조를 구별합니다.

예를 들어 String 타입의 변수는 null을 가질 수 없지만, 

String? 타입의 변수는 null을 가질 수 있습니다.

예)


그리고 String 타입은 .length에 접근할 수 있지만, 

String? 타입은 .length에 접근할 수 없습니다.


하지만 우리는 String? 타입의 변수에 .length 접근을 해야 할 경우가 있을 수 있습니다.

이런 경우 몇 가지 방법이 있습니다.


Checking for null in conditions

if .. else 조건문을 사용합니다.

val b : String? = "nullable"

val leng2 = if(b != null) b.length else -1
println(leng2)
if( b != null && b.length > 0) {
println("b.length = ${b.length}")
} else {
println("b == null, length = -1")
}


Safe Calls

위 같은 방법은 사실 귀찮습니다. 편하게 ? 를 사용하면 됩니다.

b?.length 처럼 접근할 수 있습니다.

위처럼 사용하면 b가 null 이 아니면 b.length 값을, null이면 null을 반환해줍니다.

이런 방법은 chain에서도 유용합니다.


Elvis Operator

val leng2 = if(b != null) b.length else -1

위 코드를 아래 코드처럼 간단하게 사용할 수 있습니다. 생긴게 삼항 연산자하고 비스무리하죠?


val leng3 = b?.length ?: -1


The !! Operator

이 방법은 NPE를 선호하는 사람들에게 맞는 방법입니다.

not-null 역설 연산자입니다. 모든 값을 null이 아닌 타입으로 반환하고,

null일 경우 예외를 발생시킵니다.

아래처럼 b가 null 일 경우 Exception이 발생합니다.

val b : String? = null
println(b!!.length)


Safe Casts

일반적으로 캐스팅을 할 때 타겟 타입이 맞지 않으면 ClassCastException이 발생합니다.

safe cast를 하면 ClassCastException 대신 null을 반환합니다.

아래 예제처럼 캐스팅이 안되는 조건인 경우

val a = "abc"

val aInt : Int? = a as? Int
println(aInt)

이렇게 null을 반환합니다.


Collections of Nullable Type

만약 컬렉션의 요소의 타입 중 nullable이 있고, non-null 요소를 필터링하고 싶다면

filterNotNull() 메서드를 사용하면 됩니다.

val nullableList : List<Int?> = listOf(1,2, null, 4)

val intList : List<Int> = nullableList.filterNotNull()
println(nullableList)
println(intList)


이상입니다.

다음 포스팅에서는 Exception 에 대해 공부합니다.

감사합니다.

반응형