Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- Coroutine
- 코틀린
- DataBinding
- 알고리즘
- kotlin
- activity
- ViewModel
- CustomView
- 백준
- Algorithm
- room
- LiveData
- BOJ
- CollapsingToolbarLayout
- 안드로이드
- notification
- HTTP
- onLayout
- Navigation
- Behavior
- recyclerview
- AppBarLayout
- lifecycle
- sqlite
- View
- hilt
- CoordinatorLayout
- Android
- onMeasure
- 알림
Archives
- Today
- Total
개발일지
Kotlin in A..Z (17) - 지연 초기화와 by 위임 본문
지연 초기화
인스턴스를 생성할 때 초기화를 할 필요가 없는 프로퍼티들이 존재한다. 그리고 인스턴스를 생성할 때 모든 프로퍼티를 초기화를 하는 것은 리소스에 부담을 줄 수 있다. 지연 초기화를 사용하여 프로퍼티를 사용하려 할 때 초기화를 할 수 있다.
- lateinit
- primitive type에는 할 수 없다. (Int, Long, Double...)
- var로 선언된 프로퍼티에만 가능하다
- 프로퍼티에 대한 getter와 setter를 사용할 수 없다.
- 초기화를 하지 않은 상태에서 접근하면 UninitializedpropertyAccessException을 발생한다.
코드
class Base {
lateinit var hi: String
fun action() {
// 초기화가 됐는지 확인하는 방법
if(::hi.isInitialized) {
println(hi)
}
else {
println("hi Is Not Initialized")
}
}
}
fun main() {
val base = Base()
// 아직 초기화가 되지 않은 상태
base.action()
// 초기화 진행
base.hi = "개발일지"
base.action()
}
결과
hi Is Not Initialized
개발일지
- lazy
- 람다를 전달받아 Lazy<T> 형식의 객체를 반환하는 것이다.
- 최초 getter에 lazy()에 전달받은 람다를 실행하여 저장하고 이후에 저장된 값을 반환한다.
- value로 값을 접근할 수 있다.
코드
val lazySTR = lazy { "Hello" }
println(lazySTR.javaClass)
println(lazySTR.value)
결과
class kotlin.SynchronizedLazyImpl
Hello
- lazy mode를 이용한 lazy
- Synchronized : 기본값이다, 초기화를 최초 호출되는 단 하나의 스레드에서만 처리하고 다른 스레드에서도 최초로 초기화 된 값을 사용한다.
- Publication : 여러 스레드에서 동시에 호출할 수 있고, 초기화도 여러 스레드에서 진행할 수 있다. 단 다른 스레드에서 초기화를 마친 경우 초기화를 진행하지 않고 그 값을 반환한다.
- None : 초기화가 되지 않은 경우 무조건 초기화를 진행한다. NPE를 발생할 수 있다.
코드
fun main() {
val modeSynchronized by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
"Synchronized"
}
val modePublication by lazy(LazyThreadSafetyMode.PUBLICATION) {
"Publication"
}
val modeNone by lazy(LazyThreadSafetyMode.NONE) {
"None"
}
println(modeSynchronized)
println(modePublication)
println(modeNone)
}
결과
Synchronized
Publication
None
- by 위임
하나 이상의 언터페이스를 상속받은 클래스의 인스턴스를 다른 클래스에 위임 함으로써 다른 클래스에서도 인터페이스를 사용할 수 있다.
위임을 사용하는 경우 무분별한 상속으로 야기할 수 있는 문제점(종속성)을 방지하기 위함과 표준 라이브러리의 클래스는 open으로 정의되지 않은 클래스가 많기 때문에 확장하기 위함이다.
코드
interface Run {
fun run()
}
class Parent : Run {
override fun run() {
println("Parent Run")
}
}
// parent의 인스턴스를 통해 Run 인터페이스가 구현된 Parent클래스를 위임 받는다.
// run메소드를 정의없이 사용할 수 있다. -> Parent의 run메소드를 가져옴
class Other(private val parent: Parent) : Run by parent {
}
fun main() {
val other = Other(Parent())
other.run()
}
결과
Parent Run
- by lazy
- lazy로 지연초기화를 하고 by로 위임하여 인스턴스를 저장할 수 있다.
- val로 선언된 프로퍼티에도 가능하다.
- lazy모드에 지정된 방식을 따른다.
코드
class Base {
val str: String by lazy {"123"}
}
fun main() {
val base = Base()
println(base.str)
}
결과
123
- by observable
값이 변경될 때 observable 콜백함수를 실행시킨다.
코드
import kotlin.properties.Delegates
fun main() {
var name: String by Delegates.observable("No") {
property, oldValue, newValue ->
println(property)
if(newValue == "Kang") {
println("Hi Kang")
}
else {
println("$oldValue -> $newValue")
}
}
println(name)
name = "Kang"
println(name)
name = "Tae"
println(name)
}
결과
No
var name: kotlin.String
Hi Kang
Kang
var name: kotlin.String
Kang -> Tae
Tae
- by vetoable()
값이 변경될 때 vetoable() 콜백함수를 실행시키고 반환값이 true여야 값을 바꾼다.
코드
import kotlin.properties.Delegates
fun main() {
var maxNumber: Int by Delegates.vetoable(0) {
property, oldValue, newValue ->
println(property)
oldValue < newValue
}
maxNumber = 1
println(maxNumber)
// vetoable 함수의 반환값이 false이므로 변경하지 않음
maxNumber = 0
println(maxNumber)
maxNumber = 3
println(maxNumber)
}
결과
var maxNumber: kotlin.Int
1
var maxNumber: kotlin.Int
1
var maxNumber: kotlin.Int
3
'Kotlin (코틀린)' 카테고리의 다른 글
Kotlin in A..Z (19) - 인터페이스 (0) | 2020.07.17 |
---|---|
Kotlin in A..Z (18) - companion object, object, 싱글톤 (0) | 2020.07.16 |
Kotlin in A..Z (16) - 프로퍼티 getter, setter (0) | 2020.07.15 |
Kotlin in A..Z (15) - 가시성 지시자 (0) | 2020.07.15 |
Kotlin in A..Z (14) - 상속 (0) | 2020.07.15 |
Comments