지연 초기화

Anna·2024년 6월 12일
0

코틀린

목록 보기
23/28
post-thumbnail

초기화하는 이유

  • 클래스에서는 기본적으로 선언하는 프로퍼티 자료형들은 null을 가질 수 없다.
  • 객체의 정보가 나중에 나타나는 경우 나중에 초기화 할 수 있는 방법 필요
  • 지연 초기화를 위해 lateinit과 lazy 키워드 사용

lateinit의 제한

  • var로 선언된 프로퍼티만 가능
  • 프로퍼티에 대한 게터와 세터를 사용할 수 없다.
fun main()
{
    val kildong = Person()
    kildong.test()
    kildong.name = "Kildong"   //이 시점에서 초기화됨(지연 초기화)
    kildong.test()
    println("name = ${kildong.name}")
}

class Person
{
    lateinit var name : String  //늦은 초기화를 위한 선언

    fun test()
    {
        if(!::name.isInitialized)  //프로퍼티의 초기화 여부 판단
        {
            println("not initialized")
        } else 
        {
            println("initialized")
        }
    }
}

lazy

  • 호출 시점에 by lazy{...} 정의에 의해 블록 부분의 초기화를 진행한다.
  • 불변의 변수 선언인 val에서만 사용 가능하다.
  • val이므로 값을 다시 변경할 수 없다.

lazy 1

class LazyTest
{
    init
    {
        println("init block")
    }

    private val subject by lazy {  //private로 권장하는 이유는 외부에서 사용하지 않았기 때문이다.
        println("lazy initialized")
        "Kotlin Programming"  //lazy 반환값 (람다식)
    }

    fun flow()
    {
        println("not initialized")
        println("subject one : ${subject}")  // 최초 초기화 시점!
        println("subject two : ${subject}")  //이미 초기화된 값 사용, 위 subject 블록이 구동하지 않음.
    }
}

fun main()
{
    val test = LazyTest()
    test.flow()
}

lazy 2

class Person(val name : String, val age : Int)

fun main()
{
    var isPersonInstantiated : Boolean = false  //초기화 확인 용도

    val person : Person by lazy {  //lazy 사용한 person객체의 지연 초기화
        isPersonInstantiated = true  // 이 구문으로 진입하면 true로 넣음, 인스턴스 생성되었는지 확인용
        Person("Kim", 23)   //lazy 객체로 반환됨
    }

        // 사용 방식이만 틀린거 뿐이고, lazy방식으로 정의 됨. 위임방식 알아보기!!
    val personDelegate = lazy {Person("Hong", 40) }   //위임 변수를 사용한 초기화

    println("person Init : ${isPersonInstantiated}")
    //위임 변수가 초기화 되었는지 isInitialized() 호출
    println("personDelegate Init : ${personDelegate.isInitialized()}") 

    println("person.name = ${person.name}")   //이 시점에서 초기화
    //위임 변수를 사용했을 때 한 단계가 더 들어간다.
    println("personDelegate.value.name = ${personDelegate.value.name}")  //이 시점에서 초기화

    println("person Init : ${isPersonInstantiated}")
    println("personDelegate Init : ${personDelegate.isInitialized()}")
}

0개의 댓글