1class Player(_name: String, val health: Int){2
3 //1번째로 초기화 됨4 val race = "DWARF"5 val town = "Bavaria"6 val name = _name7 val alignment: String8 private var age = 09 10 //2번째로 초기화 됨11 init{12 println("initializing player")13 alignment = "GOOD"14 }15 16 constructor(_name: String) : this(_name, 100){17 //3번째로 초기화 됨18 town = "The Shire"19 }20}21
22fun main(){23 Player("Madrigal")24}
코틀린 코드를 바이트코드로 변환 했을 때, 초기화 되는 순서는
코틀린에서는 null 안전 시스템을 위해 클래스 속성은 어느곳에서 선언되든 인스텅ㄴ스가 생성될 때 반드시 초기화 되어야한다. 그러나 기본타입을 갖는 속성이 아니고, 다른 객체를 참조하는 속성의 경우에는 선언하는 시점에서 초기화될 수 없는 경우도 있다. 이것을 지연 초기화라고 하며, 대표적인 사례가 안드로이드 프레임워크이다.
안드로이드에서는 activity클래스에서 애플리케이션의 사용자 인터페이스와 업무로직등의 모든것을 처리하며, 우리가 사용하는 컴포넌트 클래스의 인스턴스를 참조하는 속성을 갖는다. 그리고 애플리케이션이 실행될 때 우리 activity 클래스의 인스턴스가 자동 생성되고, 제일먼저 oncreate 함수가 자동 호출된다. 따라서 activity 클래스에 정의된 모든 속성은 이때 초기화 되어야한다.
지연초기화는 lateinit 키워드르 통해 나타낸다
1lateinit var alignment: String
지연초기화 속성은 유용하지만 사용하기 전에 반드시 초기화 해야 한다. 초기화가 되기 전에 사용한다면 UninitializedPropertyAccessException이 발생된다.
지연초기화 속성을 사용할 수 있는 경우
속성의 늦 초기화를 위임하여 처리할 때는 코틀린 표준 라이브러리의 lazy함수를 대리자로 사용한다. 이 함수는 람다를 인자로 받아 실행시킨다. 따라서 속성이 초기화될 때 실행하고자 하는 코드를 람다에 정의하면 된다.