-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Chapter - 08] lateinit과 Delegates.notNull 의 차이 #5
Comments
@sawooook 님
|
@JungTag 바로 달까영??! 그리고 스터디때 답변 단거 정리해주시는건 어떠세용~? |
@sawooook 좋습니당~ |
1. 원시 타입이 lateinit에서는 사용이 불가능한 반면, Delegates.notNull에서 사용이 가능한 이유?먼저 lateinit 내부 구현을 살펴봅시다. class Sample {
lateinit var prop: Prop
fun init(prop: Prop) {
this.prop = prop
}
}
class Prop(val value: Int)
fun main() {
val sample = Sample()
sample.init(Prop(10))
println(sample.prop.value)
} 이를 디컴파일해보면 다음과 같습니다. public final class Sample {
public Prop prop; // 처음엔 null, 추후 setter에 의해 초기화
@NotNull
public final Prop getProp() {
Prop var10000 = this.prop;
if (var10000 == null) {
Intrinsics.throwUninitializedPropertyAccessException("prop");
}
return var10000;
}
public final void setProp(@NotNull Prop var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.prop = var1;
} lateinit은 선언한 타입과 동일한 객체를 그대로 사용합니다. 그러면 java에서 사용되는 Wrapper 클래스(Integer, Long, Boolean 등)를 넣어주면 되는 거 아니야?라고 생각하실 수 있습니다. 코틀린에서 기본 자료형을 사용하면 기본적으로 자바의 원시 타입으로 컴파일 되고, nullable 타입으로 선언하거나 제네릭 타입으로 사용할 때에 경우 Wrapper 클래스로 컴파일 됩니다. lateinit은 제네릭 타입을 사용하지 않고(선언한 타입 그대로 사용), @NotNull 애너테이션에 의해 nullable한 값을 set할 수 없기 때문에 이러한 원시 자료형의 Wrapper 클래스 또한 사용이 불가능합니다. 그 다음으로 Delegates.notNull()의 내부구현을 살펴봅시다. public object Delegates {
public fun <T : Any> notNull(): ReadWriteProperty<Any?, T> = NotNullVar()
...
}
private class NotNullVar<T : Any>() : ReadWriteProperty<Any?, T> {
private var value: T? = null
public override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return value ?: throw IllegalStateException("Property ${property.name} should be initialized before get.")
}
public override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
this.value = value
}
} Delegates.notNull()은 lateinit과 달리 타입을 그대로 쓰는 게 아니라 NotNullVar이라는 객체에 래핑하여 사용합니다. 2. 둘의 차이 & 공통점 정리먼저 둘의 차이점을 정리하자면 다음과 같습니다.
공통점은 다음과 같습니다.
|
질문 내용을 적어주세요 📝
이부분이 있는데 왜 lateinit은 불가능하고, Delegates.notNull 은 가능할까요?!
둘이 어떤 차이가 있는지 궁금합니다!
The text was updated successfully, but these errors were encountered: