[Kotlin] lateinit 과 lazy 비교 정리

명준쓰·2023년 7월 6일
0

안녕하세요 오늘은 lateinit 과 lazy 에 대해서 설명하고 비교해보도록 하겠습니다.

lateinit

가장 간단하게 설명드리면 늦은 초기화를 하기 위해 사용하는 접근 방식입니다.

늦은 초기화란?

늦은 초기화란, 말 그대로 객체의 초기화를 늦게 한다는 것입니다. 물론 '늦은' 이기 때문에 초기화는 반드시 해주셔야 합니다.

늦은 초기화를 사용하는 이유에 대해서 설명을 해보겠습니다.

만약 여러분이 친구를 만난다고 생각해보겟습니다.

class Person {
    lateinit var name: String //친구 만날 예정

    fun setName() {
        name = "John" // 친구 만낫는대 이름이 존
    }

    fun printName() {
        if (::name.isInitialized) {
            println("Person's name: $name") // 초기화된 변수 사용
        } else {
            println("Person's name is not initialized")
        }
    }
}

fun main() {
    val person = Person()
    person.setName()
    person.printName()
}

코드를 살펴보시면 쉽게 이해하실 수 있으실겁니다.
사용할 변수에 무슨 값이 들어올지 모를때 초기화를 미뤄놀때 lateinit 을 사용합니다.
이때 값은 변할 수 있으므로 반드시 "var"로 선언을 해주셔야 합니다.
또한 Non-null 타입 변수에만 사용할 수 있으며, Nullable 변수에는 사용할 수 없습니다.
변수를 초기화하기 전에 접근하면 UninitializedPropertyAccessException예외가 발생합니다.

"lazy"란

변수에 처음 접근하는 시점에서 초기화를 수행하는 지연 초기화 기법입니다.

이해하기 쉽게 코드로 간단한 예를 들어서 설명 드리겟습니다.

fun main() {
	lateinit var text : String 
    val textLength : Int by lazy { 
    	text.length //아직 text에는 무슨 값이 들어올지 모르는 상황
       }
       
       text = "BMW" //텍스트 초기화됨 (텍스트 길이가 정해짐)
       println(textLength) // 초기화 된 텍스트 길이 출력

코드를 보시면 처음 textLength 에서는 text의 값이 없기 때문에 초기화를 할 수 없습니다.
하지만 후에 text가 초기화되며 textLength 또한 초기화가 가능해졌습니다.

선언 당시에는 초기화 할 방법이 없음 하지만 의존하는 값들이 초기화 된 이후에 초기화 가능

호출 시에 이를 어떻게 초기화 해줄 지에 대해 정의가 가능한 기법이라고 생각하면 됩니다.

코드를 보시면 lateinit 과 다르게 var 가 아닌 val을 사용하고 있습니다.
이는 단 한번의 늦은 초기화가 이루어지고 나면 값이 변하지 않는다는 것을 의미합니다.


lateinitlazy
변수가 초기화 되기 전까지는 null이지만, 나중에 반드시 초기화될 것이라는 보장이 있는 경우에 사용됩니다. 즉, null 허용 변수를 피하면서, 초기화를 뒤로 미룰 수 있습니다.변수의 초기화를 처음 사용하는 시점까지 늦출 수 있습니다. 이를 통해 리소스를 효율적으로 관리할 수 있습니다.
사용 가능한 변수 타입원시 타입을 제외한 모든 타입에 사용 가능합니다. (Int, Double 등 원시 타입에는 사용 불가)모든 변수 타입에 사용 가능합니다.
초기화 시점코드에서 명시적으로 초기화되어야 합니다. 그렇지 않으면 'lateinit property has not been initialized'라는 예외가 발생합니다.처음으로 변수에 접근하는 시점에 자동으로 초기화됩니다.
재 초기화재 초기화가 가능합니다. 즉, 변수에 다시 값 할당이 가능합니다.한번 초기화되면 재 초기화가 불가능합니다.
스레드 안전성스레드에 안전하지 않을 수 있습니다. 즉, 여러 스레드에서 동시에 초기화될 수 있습니다.스레드에 안전합니다. 기본적으로 동기화되어 있으며, 첫 접근시에만 초기화를 수행합니다.
사용 방법'lateinit var 변수이름: 타입 ''val 변수이름: 타입 by lazy { 초기화 로직 }
profile
개린이

0개의 댓글