[Android] 3(9). 코틀린 기본 문법(지연 초기화)

2 minute read


지연 초기화

코틀린의 지연 초기화는 클래스의 코드에 Nullable( ? )이 남용되는 것을 막아줍니다. 지연 초기화에는 lateinit과 laㅋy가 사용됩니다.


lateinit


개발을 하다보면 클래스 안에서 변수(프로퍼티)만 Nullable로 미리 선언하고 초기화(생성자 호출)를 나중에 해야 할 경우가 있는데, 이럴 경우 lateinit 키워드를 사용할 수 있습니다.

Nullable로 선언하는 일반적인 방법

일반적으로 처음에 null 값을 입력해두고, 클래스의 다른 메서드 영역에서 값을 입력합니다.

class Person{
    var name: String? = null
    init{
        name = "Lionel"
    }
    fun process(){
        name?.plus("Messi")
        print("이름의 길이 = ${name?.length}")
        print("이름의 첫 글자 = ${name?.substring(0,1)}")
    }
}

하지만 이러한 방식은 변수에 입력된 값의 메서드나 프로퍼티를 사용할 때 Safe Call(?.)이 남용되어 가독성을 저해합니다.


lateinit을 사용하는 방법

아래 코드와 같이 lateinit을 사용하면 Safe Call을 사용하지 않아 가독성을 높일 수 있습니다.

class Person{
    lateinit var name: String
    init{
        name = "Lionel"
    }
    fun process(){
        name.plus("Messi")
        print("이름의 길이 = ${name.length}")
        print("이름의 첫 글자 = ${name.substring(0,1)}")
    }
}

lateinit의 특징은 다음과 같습니다.

  • var로 선언된 클래스의 프로퍼티에만 사용할 수 있습니다.
  • null은 허용되지 않습니다.
  • 기본 자료형 Int, Long, Double, Float 등은 사용할 수 없습니다.

주의 사항

lateinit은 변수를 미리 선언만 해 놓은 방식이기 때문에 초기화되지 않은 상태에서 메서드나 프로퍼티를 참조하면 null 예외가 발생하여 앱이 종료됩니다. 따라서 변수가 초기화되지 않은 상황이 발생할 수 있다면, Nullable이나 빈 값으로 초기화하는 것이 좋습니다.



lazy


lazy는 읽기 전용 변수인 val을 사용하는 지연 초기화입니다.

lateinit이 입력된 값을 변경할 수 있는 반면, lazy는 입력값을 변경할 수 없습니다.


val로 먼저 변수를 선언한 후 코드의 뒤쪽에 by lazy 키워드를 사용하고 다음에 나오는 중괄호({ }) 에 초기화할 값을 써주면 됩니다.

class Company{
    val person: Person by lazy {Person()}
    init{
        // lazy는 선언 시에 초기화를 하기 때문에 초기화 과정이 필요 없습니다. 
    }
    fun process(){
        print("person의 이름은 ${person.name}") // 최초 호출하는 시점에 초기화됩니다. 
    }
}

lazy의 특징은 다음과 같습니다.

  • 선언 시에 초기화 코드를 함께 작성하기 때문에, 따로 초기화할 필요가 없습니다.
  • lazy로 선언된 변수가 최초 호출되는 시점에 by lazy{} 안에 넣은 값으로 초기화됩니다. 초기화 시점은 최초 호출되는 시점입니다.

주의 사항

지연 초기화는 말 그대로 최초 호출되는 시점에 초기화 작업이 일어나기 때문에 초기화하는 데 사용하는 리소스가 너무 크면 (메모리를 많이 쓰거나 코드가 복잡한 경우) 전체 처리 속도에 나쁜 영향을 줄 수 있습니다.

따라서 복잡한 코드를 가지고 있는 클래스라면 미리 초기화해 놓고 사용하는 것이 좋습니다.



정리


  • 코틀린의 지연 초기화 방법에는 lateinit과 lazy를 사용하는 방법이 있습니다.
  • lateinit은 lateinit var 변수: 클래스와 같이 사용하며, 클래스 안에서 변수(프로퍼티)만 Nullable로 미리 선언하고 초기화(생성자 호출)를 나중에 해야 할 때 사용합니다.
  • lazy는 val 변수: 클래스 by lazy{ 클래스() }와 같이 사용하며, 최초 호출되는 시점에 { } 안의 코드로 초기화됩니다.
  • 지연 초기화는 초기화 시의 리소스가 너무 크면 처리 속도에 안 좋은 영향을 주기 때문에 복잡한 코드를 가지고 있는 클래스라면 머리 초기화해 놓고 사용하는 것이 좋습니다.

Categories:

Updated:

Leave a comment