kotlin을 사용하다 보면 나중에 초기화를 하기 위해 lateinit 과 lazy를 사용하곤 하는데 그래서 이게 뭐가 다르다고?

일단 공식문서에서 다시 한번 lateinit과 lazy by에 대해서 슥 읽어보자.
https://kotlinlang.org/docs/properties.html#late-initialized-properties-and-variables
이런 내용이 있다.
You can use the lateinit modifier on var properties declared as:
Top-level properties.
Local variables.
Properties inside the body of a class.
For class properties:
You can't declare them in the primary constructor.
They must not have a custom getter or setter.
In all cases, the property or variable must be non-nullable and must not be a primitive type.
If you access a lateinit property before initializing it, Kotlin throws a specific exception that identifies the uninitialized property being accessed:
그니까 primary constructor에서 사용 못하고 custom getter/setter 사용 못하고 최상위 property, 지역 변수에 사용 가능하다고 되어있다.
lazy를 보자.
https://kotlinlang.org/docs/delegated-properties.html#lazy-properties
lazy() is a function that takes a lambda and returns an instance of Lazy<T>, which can serve as a delegate for implementing a lazy property. The first call to get() executes the lambda passed to lazy() and remembers the result. Subsequent calls to get() simply return the remembered result.
그니까 맨 처음 호출이 오면 그 값으로 초기화한 다음 그 뒤에 호출 할때는 초기화된 값으로 사용하게 한다. 정도로 이해된다.
그래서? 라고 할뻔 하다가 lateinit에서 한 문장을 놓쳤다.

non-nullable!
그리고 lazy의 코드 형태를 보았다.
expect fun <T> lazy(initializer: () -> T): Lazy<T>
이거 T에 뭐든 들어갈 수 있어서 Nullable이다.
그니까 잠깐 고민을 해보면