Kotlin

[Kotlin] lateinit vs lazy 정리

태오님 2025. 5. 12. 23:02

Kotlin에서는 변수를 나중에 초기화하는 방법으로 lateinit과 lazy를 사용할 수 있다. 둘 다 선언 시 즉시 초기화하지 않고 나중에 값을 설정하거나 계산할 때 사용하지만, 용도와 동작 방식이 다르다.

 

1.  lateinit

개념

  • 초기화 지연 변수(Delayed Initialization)
  • 주로 var(가변 변수)에 사용
  • null을 사용하지 않고 늦게 초기화할 수 있도록 해준다.

특징

  • nullable을 피할 수 있음 (var str: String? = null 대신 lateinit var str: String)
  • 초기화를 보장하지 않으면 런타임 에러 발생 (UninitializedPropertyAccessException)
  • 기본 타입(Int, Boolean 등)에는 사용 불가
    → non-null 객체 타입에서만 사용 가능
lateinit var name: String

fun initName() {
    name = "Kotlin"
}

fun printName() {
    println(name)
}

 

2.  lazy

개념

  • 지연 초기화(Lazy Initialization)
  • 주로 val(불변 변수)에 사용
  • 변수를 처음 사용하는 순간 초기화 코드가 실행된다.

특징

  • 스레드 세이프(thread-safe) (기본값으로 SynchronizedLazyImpl 사용)
  • 불변(immutable) 변수에 사용
  • 초기화 시점 제어 가능 (LazyThreadSafetyMode 로 동작 방식을 설정할 수 있음)
val name: String by lazy {
    println("초기화 중")
    "Kotlin"
}

fun printName() {
    println(name)
}

 

3.  자주 헷갈리는 포인트

처음에는 lateinit과 lazy가 비슷해 보인다. 둘 다 "지금은 값을 모르지만 나중에 채우겠다"는 의도로 쓰기 때문이다. 하지만 조금만 쓰다 보면 딱 두 가지에서 갈린다.

  1. var냐 val이냐
    • lateinit은 var만 가능하다.
    • lazy는 val만 가능하다.
  2. 초기화를 내가 직접 할 거냐, 시스템이 알아서 할 거냐
    • lateinit은 반드시 내가 명시적으로 초기화 해야 한다.
    • lazy는 변수를 처음 읽는 순간 자동으로 초기화된다.

또한, lateinit은 객체 타입에서만 쓸 수 있고, 기본 타입(Int, Boolean 등)에는 적용할 수 없다. 반면 lazy는 이런 제한 없이 쓸 수 있다.

lateinit을 쓰면 초기화 여부를 확인할 수 있는 ::변수명.isInitialized 같은 기능도 제공된다. 반면, lazy는 그런 기능은 없지만, 어차피 처음 접근할 때 자동으로 초기화되기 때문에 신경 쓸 일이 없다.

한마디로 말하면:

  • lateinit은 "이건 무조건 내가 채울 거야"
  • lazy는 "그냥 필요할 때 알아서 만들어줘"

4.  언제 무엇을 써야 할까? 

프로젝트를 하다 보면 이런 고민이 생긴다.

  • 뷰 바인딩 객체처럼 나중에 무조건 초기화해야 하는데, null은 쓰기 싫다 → lateinit
  • 데이터베이스 연결처럼 쓰일지 안 쓰일지 모르는데, 쓸 때만 초기화하고 싶다 → lazy

단순히 문법적 차이로 접근하면 실무에서는 계속 헷갈리게 된다. 하지만 "책임" 관점으로 보면 명확해진다.

  • lateinit은 초기화 책임이 "나한테" 있다.
    → 안 채우면 터진다.
  • lazy는 초기화 책임을 "시스템한테" 미룬다.
    → 나는 그냥 쓰기만 하면 된다.

초기화 시점, 책임, var/val 여부. 이 세 가지를 기억하면 선택은 간단하다.

 

5. 정리

  • lateinit : "나중에 직접 초기화할게, null 없이"
  • lazy : "필요할 때 알아서 초기화해 줘, 불변으로"

용도는 비슷해 보여도 mutable vs immutable, 초기화 시점에 따라 선택이 달라진다. 상황에 맞는 초기화 전략을 선택하는 것이 핵심이다.