💬

[Kotlin] lateinit の仕組み

2022/02/23に公開

Kotlin lateinit の仕組み

lateinit とは

実験コード

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