Hello, Android!
지연 초기화 본문
클래스의 프로퍼티는 선언과 동시에 초기화를 하거나
생성자에서 초기화를 하거나, 매개변수로부터 값을 초기화 하여야 한다
다른 클래스의 객체를 받아서 초기화 해야하거나 여러 이유로
프로퍼티 선언 혹은 객체 생성시 프로퍼티를 초기화 하기 힘든 경우가 있다
이런때 나중에 초기화 하여 사용하는, 지연 초기화 라는것이 있다
- 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 |