본문 바로가기
Android/Kotlin

[Android/Kotlin] lateinit 이해하기: nullable과의 차이와 지연 초기화 이해하기

by quessr 2025. 2. 25.

 

개발을 하다 보면, 변수를 선언할 때 초기값을 바로 할당하지 못하는 경우가 많습니다.

lateinit 키워드를 자주 사용했지만,

왜 굳이 nullable 대신 lateinit을 써야 하는지 깊이 고민해보지 않았습니다.

이번에 공부하면서 lateinit의 필요성과 nullable과의 차이점을 명확히 이해하게 되었고,

그 내용을 정리해보았습니다.


 

1. lateinit 키워드의 의미와 사용 이유

lateinit은 Kotlin에서 변수를 나중에 초기화할 것임을 명시하는 키워드입니다.
이를 통해 초기화 시점을 유연하게 조정할 수 있습니다.

Kotlin은 Null Safety를 보장하기 위해 변수를 선언할 때 반드시 초기화를 요구하지만,
초기값을 바로 설정할 수 없는 경우에는 lateinit 키워드를 사용할 수 있습니다.

예시 상황:

  • Android의 onCreate() 메서드 안에서 초기화가 필요한 경우
  • 특정 메서드 안에서 동적으로 값을 할당해야 하는 경우

2. lateinit의 사용법

lateinit var name: String

fun initializeName() {
    name = "John Doe"  // 나중에 초기화
}

 

  • lateinit을 사용하면 초기화 없이 선언할 수 있고,
    나중에 필요한 시점에 초기화할 수 있습니다.
  • 하지만, 초기화가 되지 않은 상태에서 변수에 접근하면
    UninitializedPropertyAccessException 예외가 발생합니다.

3. lateinit과 nullable의 차이

구분 lateinit nullable (?)
초기화 필요 여부 선언 시 초기화 불필요 초기값 필요 (또는 null)
null 허용 여부 null 불가능 null 가능
초기화 검사 방법 ::varName.isInitialized 사용 if (var != null)로 검사
예시 lateinit var name: String var name: String? = null

 

lateinitnull을 허용하지 않으면서도, 초기화 시점을 나중으로 미루고 싶을 때 사용됩니다.


4. lateinit이 사용된 코드 분석

private lateinit var graph: Array<BooleanArray>
private lateinit var visited: Array<BooleanArray>

 

 

왜 lateinit을 사용할까?

  • 초기화 시점을 나중으로 미루기 위해서
    예를 들어, main() 함수나 특정 초기화 메서드 안에서
    graphvisited를 크기에 맞게 동적으로 초기화할 수 있습니다.
fun initializeGraph(size: Int) {
    graph = Array(size) { BooleanArray(size) }
    visited = Array(size) { BooleanArray(size) }
}

 

초기화 여부 확인 방법:

if (::graph.isInitialized) {
    println("Graph has been initialized.")
}

 

  • ::graph.isInitialized를 통해 초기화 여부를 확인할 수 있습니다.
  • 초기화 전 접근 시 UninitializedPropertyAccessException이 발생합니다.

5. lateinit 없이 사용할 경우

만약 lateinit을 사용하지 않는다면, 변수를 nullable로 선언하거나, 초기화 값을 직접 할당해야 합니다.

 

Nullable로 선언한 예시:

private var graph: Array<BooleanArray>? = null

fun initializeGraph(size: Int) {
    graph = Array(size) { BooleanArray(size) }
}

 

 

하지만 이 경우, null 체크를 매번 해주어야 합니다.

if (graph != null) {
    graph!![0][0] = true
}

 

  • !! 연산자는 NPE (NullPointerException)를 발생시킬 위험이 있습니다.
  • lateinit을 사용하면 이러한 불필요한 null 체크를 피할 수 있습니다.

6. 언제 lateinit을 사용해야 할까?

적합한 경우:

  • var로 선언된 non-nullable 변수일 때
  • 초기화 시점을 나중으로 미뤄야 할 때 (예: 그래프 크기, 사용자 입력 등)
  • null 값을 허용하고 싶지 않을 때

부적합한 경우:

  • val 변수 (변경 불가능한 변수)
  • 기본 타입 (Int, Boolean 등) → lateinit 사용 불가
    (Kotlin에서는 primitive 타입에 lateinit을 사용할 수 없습니다.)
  • 초기화가 필수적이지 않은 경우 → nullable 사용을 권장

7. 결론

lateinit초기화 시점을 나중으로 미루기 위한 도구로,

Nullable 변수 대신 초기화 전까지 null 상태를 피하면서도,
초기화 후에는 안전하게 사용할 수 있도록 도와줍니다.

 

반응형