반응형
lateinit
코틀린에서는 클래스 멤버내의 프로퍼티 변수는 선언 이후, 반드시 초기화를 하거나 init 블럭 내에서 초기화를 해야 합니다.
초기화 값이 마땅치 않을 때 nullable 타입형태로 null 로 초기화 한 뒤, 실제 데이터로 값을 적용하는 것도 일종의 초기화 방법입니다.
위 방법 대신,,
lateinit 키워드를 사용하면 초기화를 미룰 수 있습니다.
하지만, lateinit 을 사용하기 위해서는 다음과 같은 제약이 있습니다.
- var 로 선언한 프로퍼티에만 사용할 수 있습니다.
- 클래스 몸체에 선언한 프로퍼티에만 사용할 수 있습니다. (주생성자의 프로퍼티에는 사용할 수 없습니다.)
- lateinit 사용한 변수는 setter()/getter()를 사용할 수 없습니다.
- 코틀린에서 기본적으로 제공하는 primitive type (Int, Boolean, Double)에도 사용할 수 없습니다.
- null 허용 프로퍼티에는 사용할 수 없습니다.
에러 예)
class User2() {
lateinit var name
get() = field.uppercase()
set(value) {
field = "Hello " + value
}
}
class User3 {
lateinit var name: String
}
초기화 하지 않고, 접근하는 경우 런타임 에러가 발생합니다.
Exception in thread "main" kotlin.UninitializedPropertyAccessException: lateinit property name has not been initialized
val user3 = User3()
println(user3.name)
안드로이드의 사용 예)
class MainActivity : AppCompatActivity() {
lateinit var mPref: SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
mPref = PreferenceManager.getDefaultSharedPreferences(this)
if(::mPref.isInitialized) {
mPref.xxxxxx
}
}
}
초기화 미루기 : lazy
프로퍼티의 초기화를 프로퍼티의 이용시점으로 미루는 방법입니다. 실제 프로퍼티를 이용하는 시점에 초기화 할 수 있습니다.
lazy 사용은 다음의 규칙이 있습니다.
- 호출 시점에 초기화가 진행됩니다.
- val로 선언한 프로퍼티에만 사용이 가능합니다.
- 클래스 몸체 이외에 최상위 레벨에서도 사용이 가능합니다.
- 기초타입에도 사용이 가능합니다.
class User2 {
val name: String by lazy {
println("name is initiaiized by lazy")
"kkang"
}
val age: Int by lazy {
println("age is initiaiized by lazy")
20
}
init {
//name = "jeong" //compile error;
//name은 by lazy로 선언되었기 때문에 init 블럭내에서 프로퍼티에 값을 설정할 수 없다.
println("init block")
}
constructor() {
//age = 30 //compile error;
//age는 by lazy로 선언되었기 때문에 init 블럭내에서 프로퍼티에 값을 설정할 수 없다.
println("constructor")
}
}
val user2 = User2()
println("1st + ${user2.name}")
println("2nd + ${user2.age}")
//output
init block
constructor
name is initiaiized by lazy
1st + kkang
age is initiaiized by lazy
2nd + 20
안드로이드에서는 실제 아래와 같이 많이 사용됩니다.
private val mediaPlayer: MediaPlayer by lazy {
MediaPlayer.create(this. R.raw.iloveyou)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mediaPlayer.start() //호출되는 시점에 초기화가 된다.
}
nullable 타입형태로 선언해서 null로 선언하고, 나중에 필요할 때 값을 입력하면 되지 라고 생각할 수도 있겠지만, null을 대입할 수 없는 프로퍼티를 굳이 null 허용으로 선언할 필요는 없습니다.
코틀린은 null 처리가 엄격합니다. null 을 대입하지 않는 프로퍼티에 단지 초기화 시점을 미루기 위해 null 허용으로 선언할 필요는 없습니다.
반응형
'Kotlin' 카테고리의 다른 글
collection (0) | 2022.03.27 |
---|---|
reduce, fold (0) | 2022.03.26 |
Scope 함수(범위 지정 함수 - apply, with, let, also, run) (0) | 2022.03.26 |
backing field <custom getter(), setter() 설정> (0) | 2022.03.26 |
val, const val (0) | 2022.03.25 |