💬
[Kotlin] lateinit の仕組み
Kotlin lateinit の仕組み
lateinit とは
- インスタンス変数を nonnull 型で宣言できないけど、nullable 型にはしたくない時に使う
- https://kotlinlang.org/docs/properties.html#late-initialized-properties-and-variables
実験コード
class Foo(){
lateinit var str: String
fun init(){
str = "Hello"
}
}
fun main(){
val f = Foo()
print(f.str)
f.init()
println(f.str)
}
$ docker container run -it --rm \
-v /path/to/kotlin/code:/app zenika/kotlin \
kotlinc /app/Lateinit.kt -include-runtime -d /app/Lateinit.jar
$ java -jar Lateinit.jar
Exception in thread "main" kotlin.UninitializedPropertyAccessException: lateinit property str has not been initialized
at Foo.getStr(Lateinit.kt:2)
at LateinitKt.main(Lateinit.kt:10)
at LateinitKt.main(Lateinit.kt)
バイトコードを覗き見
$ unzip Lateinit.jar
$ javap -p -v -s -constants Foo.class
(省略)
public final java.lang.String getStr();
descriptor: ()Ljava/lang/String;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: getfield #11 // Field str:Ljava/lang/String;
4: dup
5: ifnonnull 13
8: ldc #12 // String str
10: invokestatic #18 // Method kotlin/jvm/internal/Intrinsics.throwUninitializedPropertyAccessException:(Ljava/lang/String;)V
13: areturn
StackMapTable: number_of_entries = 1
frame_type = 77 /* same_locals_1_stack_item */
stack = [ class java/lang/String ]
LineNumberTable:
line 2: 0
LocalVariableTable:
Start Length Slot Name Signature
0 14 0 this LFoo;
RuntimeInvisibleAnnotations:
0: #7()
org.jetbrains.annotations.NotNull
(省略)
わかったこと
- getter の中で null だったら例外を投げる仕組みがある
Discussion