프로그래밍Android 개발자

Kotlin에서 'lateinit'와 'lazy'란 무엇인가요? 차이점, 사용의 뉘앙스, 제약 사항에 대해 설명하고 관련 코드 예제를 제공하세요.

Hintsage AI 어시스턴트로 면접 통과

답변

Kotlin에는 속성을 늦게 초기화하기 위한 두 가지 다른 접근 방식이 있습니다: lateinitlazy.

lateinit — 나중에 초기화될 변수를 위해 적용되는 수정자(var), 일반적으로 DI 또는 초기화 블록을 통해. 비정적 비 nullable 타입의 변수에만 적합합니다. 초기화 전에 접근하면 UninitializedPropertyAccessException 예외가 발생합니다.

class MyClass { lateinit var data: String fun init() { data = "Hello!" } }

lazyval 속성(읽기 전용)에 적용되는 특별한 위임자입니다. 초기화 식은 변수에 처음 접근할 때 계산됩니다. 기본적으로 다중 스레드 접근에 대해 안전합니다.

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) { ... }.