그동안은 코틀린의 문법 중 넓은 범위의 것들을 살펴보았다. 이제 가장 중요한 부분을 배워보자: 바로 타입 시스템이다. 코틀린에서는 새롭게 만들어진 기능, 즉 nullable 타입과 read-only collection 등을 지원한다.

#Nullability

코틀린 타입 시스템에서는 자바에서 흔히 볼 수 있는 java.lang.NullPointerException를 피할 수 있기 위해서 컴파일 시점에 null 에러를 파악할 수 있도록 명시적으로 지원한다.

/* Java */
int strLen(String s) {
return s.length();
}

자바에서는 위와 같은 함수에서 String이 null일 경우 NullPointerException 에러를 만들지만, 코틀린의 경우 String 타입이 반드시 넘겨지도록 강제하기 때문에 null이 포함된 매개변수를 넘겨 줄 수 없다. 만약 코틀린에서 null을 넘겨주고 싶다면 이를 **앨비스 연산자 ?**를 사용하여 보여줘야 한다.

fun strLen(s: String) = s.length
>>> strLen(null)
ERROR: Null can not be a value of a non-null type String

//명시적으로 null 타입을 넘겨주기 때문에 ? 사용
un strLenSafe(s: String?) = ...

null 타입을 명시한 후에는 할 수 있는 일이 제한되어 있다.

  1. 더 이상 fun strLenSafe(s: String?) = s.length()처럼 메소드 호출 불가
  2. null 타입이 아닌 값에게 val x: String? = null처럼 null 할당 불가
  3. null 타입이 아닌 파라미터를 가진 함수에게 null 타입 pass 불가

단, if를 통해 null을 체크해 준 다음에는 컴파일러가 컴파일 하는 것이 가능하다.

fun strLenSafe(s: String?): Int =
if (s != null) s.length else 0

#타입이란 무엇인가?

타입이란 “해당 타입에 대해 가능한 값들을 집합으로 모아 놓은 분류”이다.

자바에서는 String 타입에서 String 값과 null 값 둘 중에 하나를 가질 수 있다. 따라서 이런 경우 추가적인 타입 체크가 필요하다.

<aside> 📌 자바에서도 @Nullable@NotNull를 활용하여 null 타입 체크가 가능하지만, 이는 별로 유용하지 않다. 또 다른 해결법은 Optional class를 활용하여 null 타입을 감싸는 것이지만, 이는 더 복잡한 코드를 생성하게 된다.

</aside>

이러한 자바의 문제점을 코틀린은 Nullable 타입을 제공함으로써 손쉽게 해결 가능하다. NullableNone-null 을 구분함으로 인해 어떠한 값이 어떤 계산을 할 수 있는지 명확하게 이해할 수 있다.

#Safe call operator: “?.”

해당 연산자는 null 체크와 동시에 메소드를 호출하는 역할을 한다.

s?.toUpperCase()
//같은 의미
if (s != null) s.toUpperCase() else null.