lateinit 프로퍼티와 달리 lazy 프로퍼티는 불변 프로퍼티가 아니다. lazy 프로퍼티는 일단 초기화된 다음에는 변경되지 않는다.
// error: type 'Lazy<String>' has no method 'setValue(Chapter4, KProperty<*>, String)' and thus it cannot serve as a delegate for var (read-write property) var text by lazy { "Hello" }
디폴트로 lazy 프로퍼티는 스레드 안전(thread-safe)하다. 즉, 다중 스레드 환경에서도 값을 한 스레드 안에서만 계산하기 때문에 lazy 프로퍼티에 접근하려는 모든 스레드는 궁극적으로 같은 값을 얻게 된다.
코틀린 1.1부터는 지역 변수에도 위임을 쓸 수 있게 됐다. 이 기능을 사용하면 함수 본문에서 지연 변수를 정의할 수 있다.
fun longComputation(): Int {...} fun main(args: Array<String>) { val data by lazy { longComputation() } // lazy 지역 변수 val name = args.firstOrNull() ?: return println("$name: $data") // name이 널이 아닐 때만 data에 접근할 수 있음 }
지금 현재 위임 프로퍼티에 대해서는 스마트 캐스트를 사용할 수 없다는 점에 유의하라. 위임은 구현이 다 다를 수 있기 때문에 커스텀 접근자로 정의된 프로퍼티처럼 다뤄진다. 그리고 이 말은 위임을 사용한 지역 변수의 경우에도 스마트 캐스트를 쓸 수 없다는 뜻이기도 하다.
fun main() {
val data by lazy { readLine() }
if (data != null) {
// error: smart cast to 'String' is impossible, because 'data' is a property that has open or custom getter
println("Length: ${data.length}")
}
}
lazy 프로퍼티와 lazy 지역 변수는 다르지 않다. 현재로서는 이 둘의 값이 초기화된 다음에 실제로 값이 바뀌지 않더라도 스마트 캐스트를 적용할 수 없다.