Kotlin에는 속성을 늦게 초기화하기 위한 두 가지 다른 접근 방식이 있습니다: lateinit과 lazy.
lateinit — 나중에 초기화될 변수를 위해 적용되는 수정자(var), 일반적으로 DI 또는 초기화 블록을 통해. 비정적 비 nullable 타입의 변수에만 적합합니다. 초기화 전에 접근하면 UninitializedPropertyAccessException 예외가 발생합니다.
class MyClass { lateinit var data: String fun init() { data = "Hello!" } }
lazy — val 속성(읽기 전용)에 적용되는 특별한 위임자입니다. 초기화 식은 변수에 처음 접근할 때 계산됩니다. 기본적으로 다중 스레드 접근에 대해 안전합니다.
val config: Config by lazy { loadConfigFromFile() }
lateinit은 원시 타입 및 val과 함께 작동하지 않습니다.lazy는 재초기화를 허용하지 않습니다.lateinit은 보장된 나중에 할당될 변수(예: DI 프레임워크를 통해 또는 Android 생명주기에서)를 위해 사용됩니다.lazy는 값의 계산 비용이 높고 필요하지 않을 수 있는 경우에 대한 지연 계산을 위해 사용됩니다.Int 타입의 속성에
lateinit을 사용할 수 있나요?
답변: 아니오. lateinit은 비 null 객체 타입에서만 작동합니다. 원시 타입 및 nullable 타입에서는 사용할 수 없습니다. lateinit var a: Int를 선언하려고 하면 컴파일 오류가 발생합니다.
이야기
교육 프로젝트에서 변수를 lateinit var config: Config?로 선언했으나, 컴파일러가 이를 허용하지 않았습니다 — 시간을 절약했지만, 예상과 다르게 작동하는 이유를 이해해야 했습니다.
이야기
Android 애플리케이션에서 호출 전에 lateinit 속성의 초기화 여부를 확인하는 것을 잊었습니다. 이로 인해 프로덕션에서 애플리케이션이 충돌했습니다 — 디자이너가 onCreateView 전에 속성에 접근하려고 했습니다. 추가 검사를 통해 문제를 해결했습니다.
이야기
다중 스레딩을 사용 중인 개발자가 매개변수를 전달하지 않고 자원 소모가 큰 객체를 초기화하기 위해 by lazy를 사용했습니다. 기본적으로 위임자가 스레드 안전하지 않다고 생각했습니다. 결과적으로 릴리스에서 레이스 조건 문제가 발생했습니다. 적절한 매개변수를 전달하여 lazy를 해결했습니다: by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { ... }.