-
코틀린 타입 시스템 - null 관련Kotiln 2019. 7. 19. 16:05
null 가능성(nullability) 은 NullPointerException 오류를 피할 수 있게 돕기 위한 코틀린 타입 시스템의 특성이다.
null이 될 수 있는 타입
변수의 타입 뒤에 ? 를 붙이면 null 참조를 저장할 수 있다는 뜻이다.
var x: String? = null
?.
안전한 호출 연산자?. 연산자는 null 검사와 메소드 호출을 한번의 연산으로 수행한다.
var allCaps: String? = s?.toUpperCase()
?:
엘비스 연산자null 대신 사용할 디폴트 값을 지정할 때 사용한다.
var str: String = s ?: "" // s가 null 이면 빈 문자열("")이다
as?
안전한 캐스트값을 대상 타입으로 변환할 수 없으면 null을 반환한다.
var foo = bar as? String
일반적으로 엘비스 연산자와 함께 사용한다.
var foo = bar as? String ?: ""
!!
null 아님 단언 (not-null assertion) 연산자어떤 값이든 null이 될 수 없는 타입으로 강제로 바꿀 수 있다.
null 에 대해 !! 를 적용하면 NullPointerException 이 발생한다.let
함수안전한 호출 연산자 (?.) 와 함께 사용하여 원하는 식의 결과가 null 이 아닐 때 수행하는 로직이 있을 때 사용한다.
foo?.let{ ... it ... }
foo != null 이면 it 은 람다 안에서 null 이 아니다.
foo == null 이면 아무 일도 일어나지 않는다.나중에 초기화할 프로퍼티
코틀린에서는 클래스 안의 null 이 될 수 없는 프로퍼티를 생성자 안에서 초기화하지 않고 특별한 메소드 안에서 초기화할 수 없다.
lateinit
변경자를 붙여서 프로퍼티를 나중에 초기화할 수 있다.
나중에 초기화하는 프로퍼티는 항상var
여야 한다 .
초기화하기 전에 프토퍼티에 접근하면 예외가 발생한다.null이 될 수 있는 타입 확장
null이 될 수 있는 타입에 대한 확장 함수를 정의하면 null 값을 다루는 강력한 도구로 활용할 수 있다.
예로 String? 타입의 수신 객체에 대해 호출할 수 있는 isNullOrEmpty 나 isNullOrBlank 메소드가 있다.var str: String? = null if(str.isNullOrBlank()){ println("str is Null or Blank") }
안전한 호출 없이도 null이 될 수 있는 수신 객체 타입에 대해 선언된 확장 함수를 호출 가능하다.
isNullOrBlank 함수는 내부적으로 다음과 같이 정의되어 있다.
fun String?.isNullOrBlank() : Boolean = this == null || this.isBlank()
타입 파라미터의 null 가능성
코틀린에서는 함수나 클래스의 모든 타입 파라미터는 기본적으로 null이 될 수 있다.
타입 파라미터 T 를 클래스나 함수 안에서 타입 이름으로 사용하면 이름 끝에 ? 가 없더라도 T 가 null이 될 수 있는 타입이다.fun <T> printHashCode(t: T){ println(t?.hashCode()) } printHashCode(null)
타입 파라미터가 null이 아님을 확실히 하려면 null이 될 수 없는 타입 상한(upper bound) 을 지정해야 한다.
타입 상한을 지정하면 null이 될 수 있는 값을 거부하게 된다.fun <T: Any> printHashCode (t: T){ println(t.hashCode()) } printHashCode(null) // error printHashCode(42) // ok
null 가능성과 자바
자바 코틀린 @Nullable String String? @NotNull String String 자바에서 null 가능성 애노테이션이 없는 경우 코틀린의 플랫폼 타입이 된다.
플랫폼 타입
코틀린이 null 관련 정보를 알수 없는 타입을 말한다.
그 타입을 null이 될 수 있는 타입으로 처리해도 되고 null이 될 수 없는 타입으로 처리해도 된다.
null 이 될 수 없는 타입에 null 이 들어가는 경우 NullPointerException이 발생한다.
코틀린에서 플랫폼 타입을 선언할 수는 없으며 자바 코드에서 가져온 타입만 플랫폼 타입이 된다.
하지만 IDE나 컴파일러 오류 메시지에서는 플랫폼 타입을 볼 수 있다.val i: Int = person.name > Error: Type mismatch: inferred type is String! but Int was expected
코틀린 컴파일러가 표시한
String!
라는 타입은 자바 코드에서 온 타입니다.!
표기는String!
타입의 null 가능성에 대해 아무 정보도 없다는 뜻이다.상속
코틀린에서 자바 메소드를 오버라이드 할 때 그 메소드의 파마리터와 반환 타입을 null 이 될 수 있는 타입으로 선언할지 null 이 될 수 없는 타입으로 선언할지 결정해야 한다.
구현 메소드를 다른 코틀린 코드가 호출할 수 있으므로 코틀린 컴파일러는 null 이 될 수 없는 타입으로 선언한 모든 파라미터에 대해 null 이 아님을 검사하는 단언문을 만들어준다.
자바 코드가 그 메소드에게 null 값을 넘기면 이 단언문이 발동돼 예외가 발생한다. 파라미터를 메소드 안에서 결코 사용하지 않아도 이런 예외는 피할 수 없다.참고 도서 : Kotlin in Action (2017)
반응형'Kotiln' 카테고리의 다른 글
코틀린 - 함수의 정의와 호출 (0) 2019.07.24 코틀린 기초 (0) 2019.07.23 코틀린 - 연산자 오버로딩과 기타 관례 (0) 2019.07.23 코틀린 타입 시스템 - 컬렉션과 배열 (0) 2019.07.22 코틀린 타입 시스템 - 원시 타입 (0) 2019.07.19