본문 바로가기
Kotlin Language/Kotlin 기본 문법

Kotlin(코틀린) - 지연 초기화(lateinit , lazy)

by Classic Master 2023. 12. 7.
728x90

지연 초기화 ( lateinit, lazy ) ?

  • lateinit과 lazy는 모두 Kotlin에서 변수를 지연 초기화하는 데 사용되는 기술입니다. 그러나 두 가지 기술은 목적과 사용법에서 차이가 있습니다.
  • 두 기능은 초기화를 나중으로 미루는데 사용되지만, lateinit은 초기화 이전에는 사용할 수 없고, lazy는 처음 사용될 때 초기화되며 이후에는 더 이상 초기화하지 않습니다. 선택은 상황과 목적에 따라 다르며, lateinit은 var 변수에, lazy는 val 변수에 사용됩니다.

lateinit

  • lateinit은 주로 클래스의 프로퍼티에 사용되며, 선언 이후 어느 시점에서나 초기화할 수 있는 기능을 제공합니다. 주로 의존성 주입이나 특정 메서드에서 초기화해야 하는 경우에 사용됩니다.
class Example {
    lateinit var name: String

    fun initializeName() {
        name = "My name"
    }
    fun printName() {
        // 초기화 여부를 확인하는 방법
        if (::name.isInitialized) {
            println(name)
        } else {
            println("초기화 되지않음..")
        }
    }
}
fun main() {
    val example = Example()
    example.printName()  // 출력: "초기화 되지않음..
    example.initializeName()
    example.printName()  // 출력: My name
}
  • Example 클래스는 lateinit var name: String이라는 지연 초기화 프로퍼티를 가지고 있습니다. 초기화는 initializeName 메서드에서 이루어집니다.
  • 그리고 main 함수에서는 Example 클래스의 인스턴스를 생성하고, 초기화되지 않은 상태에서 printName 메서드를 호출한 후, initializeName 메서드를 사용하여 name을 초기화하고 다시 printName 메서드를 호출합니다.
  • :: 는 참조연산자입니다. 주로 함수형 프로그래밍에서 람다 함수나 고차 함수를 사용할 때, 함수나 클래스를 간결하게 참조하고 활용하는 데에 자주 활용됩니다. 이것은 코드의 가독성을 높이고, 함수형 프로그래밍의 특성을 코틀린에서 더 쉽게 활용할 수 있도록 도와줍니다.

 

lazy

  • lazy는 프로퍼티를 처음 사용할 때까지 초기화하지 않고, 처음 사용될 때 한 번만 초기화하는 데 사용됩니다. 주로 계산 비용이 높은 초기화나 여러 번 사용되지 않는 초기화에 유용합니다.
val lazyValue: String by lazy {
    println("lazyValue를 초기화합니다.")
    "안녕, Lazy!"
}
fun main() {
    println("처음으로 lazyValue에 접근: ${lazyValue}")
    println("다시 lazyValue에 접근: ${lazyValue}")
}
  • lazyValue는 처음 사용될 때 초기화되며, 두 번째로 접근하면 초기화가 다시 일어나지 않습니다. by lazy를 사용하여 초기화 코드 블록을 정의합니다.

 

class Player {
    val playM: Map<String, String> by lazy {
        println("사용자 정보를 로딩 중입니다...")
        // 실제로 사용자 정보를 데이터베이스나 외부 소스에서 가져오는 코드
        mapOf("이름" to "홍길동", "나이" to "30", "직업" to "프로그래머")
    }
}
fun main() {
    val player = Player()
    
    // 사용자 정보를 처음 사용할 때 초기화
    println("사용자 이름: ${player.playM["이름"]}")
    
    // 이미 초기화된 정보를 다시 사용
    println("사용자 나이: ${player.playM["나이"]}")
}

 

  • 이 코드는 Player 클래스를 정의하고, 그 안에 playM이라는 지연 초기화된 맵(Map) 프로퍼티를 가지고 있습니다. 사용자 정보를 가져오는 부분은 실제로 데이터베이스나 외부 소스에서 가져오는 것을 가정한 가상의 코드입니다.
  • 여기서 사용된 주요 개념은 lazy입니다. lazy는 프로퍼티를 처음으로 사용할 때까지 초기화를 지연시키는 데에 사용됩니다. 이렇게 함으로써 필요한 경우에만 초기화를 수행하고 불필요한 리소스 낭비를 방지할 수 있습니다.

차이점

lateinit

  • var 키워드와 함께 사용되며, 변수의 값을 나중에 변경할 수 있습니다.
  • 클래스의 일반 프로퍼티로 사용됩니다.
  • 사용 전에 초기화되어야 하며, 초기화되지 않은 상태에서 사용하면 예외가 발생합니다.
  • 주로 의존성 주입 등에서 객체를 생성할 때 초기화되는 경우에 사용됩니다.

lazy

  • val 키워드와 함께 사용되며, 한 번 초기화되면 변경할 수 없습니다.
  • 클래스의 프로퍼티로 사용됩니다.
  • 사용할 때 초기화되며, 초기화된 이후에는 값이 변경되지 않습니다.
  • 주로 초기화에 많은 비용이 들거나, 초기화가 불필요한 경우에 사용됩니다.
728x90
반응형