[Kotlin] LateInit vs By Lazy

3241 단어 백엔드kotlinkotlin

늦은 초기화를 위해 lateinit 과 by lazy를 비교한 포스트

🍎 늦은 초기화란?

클래스 안에서 변수 선언만 해 놓고,
나중에 값을 사용할 때 값을 초기화 시켜 주고 싶을 때가 있다.

이럴 때 사용 가능한 방법 중에는 아래와 같이 일단 null로 설정해 준 뒤 나중에 바꾸는 방법이 있기는 하다.

var x : String? = null

하지만 두 가지, 마음에 걸리는 상황이 생길 수 있다.

1) x의 값이 변할 수는 있지만, 절대 null이어서는 안 되는 경우 -> 처음에 nullable한 <String?>으로 초기화해주는 것이 부적절함

2) x의 값이 처음 한 번만 정해지면 다시는 변하지 않는 경우 -> x가 var일 이유가 없음

애초에 '나중에 쓸 것'이라는 걸 알고 있는데, '왜 처음에 null로 고정을 해 주어야 하냐?' 라는 문제다.

이 문제를 해결 하기 위해 lateinit과 by lazy를 사용한다.


🍊 late init

lateinit 조건

  • lateinit은 꼭 변수를 부르기 전에 명시적으로 초기화 시켜야 한다.

  • var(mutable)에서만 사용이 가능하다
    (var이기 때문에 언제든 초기화를 변경할 수 있다.)

  • null을 통한 초기화를 할 수 없다.

  • 초기화를 하기 전에는 변수에 접근할 수 없다.
    (lateinit property subject has not been initialized 오류 발생)

  • 변수에 대한 setter/getter properties 정의가 불가능하다.

  • primitive type에서는 활용이 불가능하다.


🍑 late init 사용법

lateinit var x : String
x = "Initialize here"
println(x)

x에 값이 들어가기 전에 x는 null이 아니라 uninitialized(초기화되지 않음) 상태로 존재하기 때문에 lateinit property subject has not been initialized 오류 발생


🍓 by lazy

by lazy는 late inint에 비해상대적으로 편하게 사용이 가능하며, 실수할 일도 줄어든다.

  • 호출 시점에 by lazy 정의에 의해서 자동으로 초기화를 진행한다.

  • val(immutable)에서만 사용이 가능하다.
    (val이므로 값을 변경하는게 불가능하다.)

  • 초기화를 위해서는 함수명이라도 한번 적어줘야 한다.

  • lazy을 사용하는 경우 기본 Synchronized로 동작한다.


🍋 by lazy 사용법

lateinit var inputValue : String
val x : Int by lazy { inputValue.length }
inputValue = "Initialize here"
println(x)

이 코드의 경우, x는 inputValue라는 문자열의 길이를 받아와야 한다.

그런데 inputValue는 lateinit으로 설정되어 있기 때문에, 아직 그 길이를 알 수가 없다.

무조건 inputValue가 제대로 값을 가지게 된 후에 x를 활용할 예정이라면, 이 때 이용할 수 있는 문법이 by lazy다.

x는 변수가 '처음 사용되는 순간'인 4번째 줄의 println에서 inputValue.length로 자동으로 초기화된다.

x를 사용하기 전에 inputValue 변수만 명시적으로 초기화를 해 주었다면,

어디에서 호출하든 특별히 추가적인 선언문을 작성할 필요가 없는 것이다.

좋은 웹페이지 즐겨찾기