Hello, Android!

지연 초기화 본문

Kotlin

지연 초기화

lwndnjs93 2020. 3. 22. 17:11

클래스의 프로퍼티는 선언과 동시에 초기화를 하거나

생성자에서 초기화를 하거나, 매개변수로부터 값을 초기화 하여야 한다

다른 클래스의 객체를 받아서 초기화 해야하거나 여러 이유로 

프로퍼티 선언 혹은 객체 생성시 프로퍼티를 초기화 하기 힘든 경우가 있다

이런때 나중에 초기화 하여 사용하는, 지연 초기화 라는것이 있다

 

- lateinit 지연 초기화

프로퍼티 선언시 lateinit 키워드를 사용하면 초기화 하지 않은 프로퍼티도

컴파일러에게 나중에 초기화 한다고 알려주어, 컴파일이 가능하다

 

프로퍼티 carType에 lateinit키워드가 없었다면 프로퍼티 선언과 동시에 초기화를 하거나

생성자에서 받은 값을 할당해야만 한다

하지만 lateinit으로 지연 초기화를 하겠다고 알렸기 때문에  

main메서드에서 객체 생성시 문제가 없고 panamera.carType = "Fastback" 으로

객체 생성 후에 프로퍼티를 초기화 하는것이 가능하다

지연 초기화를 사용할때는 객체 생성시 당장 프로퍼티의 값이 없기 때문에

잊지말고 꼭 추후에 프로퍼티를 초기화 해야한다

 

Car클래스의 if문에서 !::carType.isInitialized 라고 하였는데

이는 carType이 초기화 되었는지 판단하는 내용이다

코틀린에서 :: 더블콜론은 리플렉션을 위해 사용한다

 

프로퍼티만이 아닌, 객체의 지연 초기화도 가능하다

이번에는 CarInfo라는 클래스의 선언을 main메서드의 밖에 하였다

하지만 lateinit이 있기때문에 main밖에서 선언할 당시에 초기화를 하지 않아도 된다

대신 main에서 사용할때 각각의 프로퍼티를 초기화 하였다

 

이렇게 lateinit으로 나중에 초기화 하는것이 가능한데 제약사항이 존재한다

1. 프로퍼티의 지연 초기화를 할때는 var로 선언된 프로퍼티만 가능하며

2. lateinit을 사용하게 될 경우 프로퍼티의 접근자 함수 get(), set()를 사용할 수 없다

 

- lazy를 이용한 지연 초기화

initlate를 이용한 지연 초기화 에서는 제약조건이 var로 선언된 프로퍼티만 가능하다고 하였다

만약 읽기만 가능한 val 변수를 지연 초기화 하기 위해서는 lazy를 이용하여야 한다

main에서 LazyTest의 객체를 생성하게 되면 가장 먼저 init이 실행이 된다

하지만 이 타이밍에서도 프로퍼티 tmp는 by lazy가 있기때문에 초기화되지 않는다

객체 생성후 flow를 호출하는데 이때 두번째 println에서 프로퍼티 tmp를 참조하는데 

이때 tmp가 초기화 되어 {} 안의 내용이 실행된다

세번째 println에서도 tmp를 참조하지만 이미 초기화 하였기때문에 반환값인 "Hello, Kotlin!!"만

반환하게 된다

 

lazy를 이용하여 객체를 지연초기화 하는것도 가능하다

lazyTest에서는 by lazy를 통해 객체의 지연초기화를 하고있다

lazy1은 lazy를 사용하여 지연 초기화를 하고 있다

이 둘은 모두 lazy의 블록에서 초기화를 실행하게 된다

하지만 특이한 점으로는 초기화 되는 타이밍이 객체의 프로퍼티, 메서드에 접근하는 타이밍에 초기화가 된다

즉 laztTest와 lazy1의 init을 확인하는 println에서는 아직 초기화 전 단계 이고

각각의 tmp1에 접근하여 출력하는 println에서 tmp1을 참조하는 타이밍에 초기화가 이루어진다

 

'Kotlin' 카테고리의 다른 글

by를 이용한 위임  (0) 2020.03.23
리플렉션 (Reflection)  (0) 2020.03.22
프로퍼티 접근자  (0) 2020.03.21
클래스의 관계  (0) 2020.03.20
지시자  (0) 2020.03.17