본문 바로가기
Kotlin/커니의 코틀린

널이 될 수 있는 타입 / 될 수 없는 타입

by 몽슬몽슬 2020. 9. 22.

커니의 코틀린 책의 내용을 요약한 글입니다. 

 

자바의 널(null) 처리

프로그래밍을 하면서 가장 많이 마주치는 버그 중 하나로 NPE(null pointer exception) 를 들 수 있을 것입니다.

자바에서는 NPE 를 방지하기 위해 어노테이션의 도움을 받아 널 허용 여부를 다음과 같이 구분합니다. 

// 널 값을 허용
@Nullable
String name;

// 널 값을 허용하지 않음
@NonNull
String name;

그러나 어노테이션으로 널 어용 여부를 확인하는 것은 Android Lint 와 같은 정적 분석 도구에서 지원하는 기능이기 때문에 여전히 NPE(null pointer exception) 가 발생할 여지가 있습니다. 

위의 코드에서도 보다시피 NonNull 로 선언한 변수를 초기화하지 않아도 Lint 가 경고만 해 줄 뿐, 컴파일 단계에서 오류가 발생하지 않습니다. 이 변수를 어딘가에서 널이 아니라는 가정하에 사용한다면, 당연히 NPE 가 발생할 것입니다. 

 

코틀린의 널(null) 처리

코틀린에서는 이러한 문제점을 해결하기 위해 모든 타입에 명시적으로 널 허용 여부를 함께 표기하도록 합니다. 

별도 표기가 없는 타입은 널 값을 허용하지 않고, 타입 뒤에 ? 를 붙여주면 해당 변수는 널 값을 가질 수 있게 됩니다. 

// 널 값을 허용
val name: String?

// 널 값을 허용하지 않음
// 초기화하지 않거나, null 을 대입할 경우 컴파일 에러
val name: String = "Bob"

코틀린에서는 널 값을 가질 수 없는 변수를 초기화하지 않거나, null 을 대입할 경우 컴파일 에러가 발생하기 때문에 자바에 비해 널 처리를 더욱 신뢰성있게 할 수 있고, NPE 가 발생할 위험이 낮아집니다.

 

자바로 작성된 클래스의 널 처리

일부 자바 자료형은 다음과 같이 코틀린의 자료형으로 처리됩니다.

타입 뒤의 ! 는 해당 타입이 널 허용 여부에 대한 정보를 포함하지 않음을 나타내며 플랫폼 타입이라고 부릅니다. 

Java

Kotlin

  java.lang.Annotation

  kotlin.Annotation!

  java.lang.CharSequence

  kotlin.CharSequence!

  java.lang.Cloneable

  kotlin.Cloneable!

  java.lang.Comparable

  kotlin.Comparable!

  java.lang.Enum

  kotlin.Enum!

  java.lang.String

  kotlin.String!

  java.lang.Throwable

  kotlin.Throwable!

 

플랫폼 타입은 자동으로 지정되는 타입으로 개발자가 직접 사용할 수 없습니다. 플랫폼 타입의 객체는 널이 될 수 있는 타입과 될 수 없는 타입에 자유롭게 할당할 수 있습니다. 그러나 null 값을 가지는 객체를 널이 될 수 없는 타입에 대입하면 NPE 가 발생할 수 있기 때문에 플랫폼 타입의 객체를 사용할 경우에는 항상 객체의 널 여부를 확인해주어야 합니다.

이러한 불편함 때문에 자바에서 널리 쓰이는 어노테이션을 코틀린이 자동으로 인식해서 널이 될 수 있는 타입과 될 수 없는 타입을 구분해주지만, 코틀린으로 작성되지 않은 곳(예를들어, JSON 파싱 결과)에서 생성된 플랫폼 타입의 객체는 널 여부를 검증할 수 없기 때문에 항상 주의해야 합니다. 

'Kotlin > 커니의 코틀린' 카테고리의 다른 글

13장. Rxjava 적용하기  (0) 2020.09.25

댓글