프로그래밍Android 개발자

Kotlin에서의 늦은 초기화 속성('lateinit var')는 어떻게 작동하며, nullable 속성과의 차이점 및 사용할 상황은 무엇인가요?

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

답변

질문의 역사

Kotlin은 타입 안전성과 null 포인터 회피에 중점을 두지만, 종종 변수의 지연 초기화가 필요합니다. 예를 들어, dependency injection 또는 Android Activity에서입니다. 이를 위해 lateinit 수식어가 추가되었습니다.

문제

일반 속성은 필수 초기화를 요구하거나 nullable이어야 합니다. 늦지만 필수 초기화가 보장될 때 불편합니다. nullable 타입을 사용하는 것은 코드를 복잡하게 만들고 추가적인 null 검사가 필요합니다.

해결책

lateinit은 초기화되지 않은 속성을 만들 수 있지만 첫 사용 전까지 초기화할 것이라고 컴파일러에게 약속할 수 있습니다. 생성자에서 초기화할 필요 없이 나중에 초기화할 수 있습니다.

class UserViewModel { lateinit var repository: UserRepository fun onCreate() { repository = UserRepository() } fun getData() = repository.load() }

주요 특징:

  • null을 사용하지 않고 초기화를 지연할 수 있습니다.
  • 초기화되지 않은 lateinit 속성에 접근할 경우 UninitializedPropertyAccessException 발생
  • var에만 해당하며 기본 타입(Int, Double 등)에는 적용되지 않음

함정이 있는 질문들.

val 속성에 대해 lateinit을 사용할 수 있나요?

아니요. lateinit은 var에만 작동하며, val은 즉시 한 번만 초기화되어야 하거나 getter를 통해 초기화되어야 합니다.

Int, Boolean, Double 등의 기본 타입에 대해 lateinit이 작동하나요?

아니요. 객체 참조 타입에 대해서만 작동합니다. 기본 타입에는 nullable 타입을 사용하세요.

초기화 전에 lateinit 속성에 접근하면 어떻게 되나요?

Kotlin은 UninitializedPropertyAccessException을 발생시킵니다:

lateinit var foo: String println(foo) // 예외

일반적인 오류와 안티 패턴

  • lateinit 속성을 초기화하는 것을 잊었을 경우 — 애플리케이션이 중단됩니다.
  • isInitialized 검증이 필요한 곳에서 사용
  • 기본 타입 및 val에 적용

실생활 예시

부정적 사례

개발자는 lateinit var item: String을 선언하고 getItem 메소드를 호출하기 전까지 초기화하지 않았습니다. 결과: 애플리케이션이 중단됨.

장점:

  • 모든 것이 올바르게 초기화되면 nullable을 피할 수 있습니다.

단점:

  • 생명 주기를 혼동하여 런타임 예외를 얻을 위험이 있음.

긍정적 사례

Android Activity: lateinit var presenter, onCreate에서 초기화. 모든 생명 주기 메소드에서 presenter를 사용하는 것이 안전합니다: null 안전성 필요 없음.

장점:

  • 가독성이 향상되고 불필요한 검사를 피할 수 있습니다.
  • 필수 초기화를 보장합니다.

단점:

  • 초기화 호출 순서를 명시적으로 관리해야 함.