kotlinでのinit、constructor、companion object呼び出し順序

4626 ワード

package com.androidtv.pos

/**
 * @author wuqiqi
 * date on 2020/8/19
 * describe  
 */
class Apple {

    private var speak: String = " "

    /*  */
    constructor(){
        println(" constructor() ")
    }

    /*  */
    constructor(name:String, age:Int):this(){
        println(" constructor(name:$name, age:$age)")
    }

    init {
        println("Apple init")
    }

    init {
        println("Apple init:name:${speak}")
    }

    /* */
    companion object {
        val instance: Apple by lazy {
            Apple("wqq", 100)
        }

        /* */
        init {
            println("companion init 1")
        }

        init {
            println("companion init 2")
        }
    }
}

App()を呼び出し、結果が表示されます.
exclude patterns:
companion init 1
companion init 2
Apple init
Apple init:name: 
 constructor() 

パラメトリック構築メソッドを呼び出し、結果が表示されます.
exclude patterns:
companion init 1
companion init 2
Apple init
Apple init:name: 
 constructor() 
 constructor(name:heihei, age:28)

kotlin回転javaのコードを見てみましょう.
package com.androidtv.pos;

import kotlin.Lazy;
import kotlin.LazyKt;
import kotlin.Metadata;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {1, 1, 18},
   bv = {1, 0, 3},
   k = 1,
   d1 = {"\u0000\u001a
\u0002\u0018\u0002
\u0002\u0010\u0000
\u0002\b\u0002
\u0002\u0010\u000e
\u0000
\u0002\u0010\b
\u0002\b\u0004\u0018\u0000 \t2\u00020\u0001:\u0001\tB\u0007\b\u0016¢\u0006\u0002\u0010\u0002B\u0017\b\u0016\u0012\u0006\u0010\u0003\u001a\u00020\u0004\u0012\u0006\u0010\u0005\u001a\u00020\u0006¢\u0006\u0002\u0010\u0007R\u000e\u0010\b\u001a\u00020\u0004X\u0082\u000e¢\u0006\u0002
\u0000¨\u0006
"}, d2 = {"Lcom/androidtv/pos/Apple;", "", "()V", "name", "", "age", "", "(Ljava/lang/String;I)V", "speak", "Companion", "app"} ) public final class Apple { private String speak; @NotNull private static final Lazy instance$delegate; public static final Apple.Companion Companion = new Apple.Companion((DefaultConstructorMarker)null); public Apple() { this.speak = " "; String var1 = "Apple init"; boolean var2 = false; System.out.println(var1); var1 = "Apple init:name:" + this.speak; var2 = false; System.out.println(var1); var1 = " constructor() "; var2 = false; System.out.println(var1); } public Apple(@NotNull String name, int age) { Intrinsics.checkParameterIsNotNull(name, "name"); this(); String var3 = " constructor(name:" + name + ", age:" + age + ')'; boolean var4 = false; System.out.println(var3); } static { instance$delegate = LazyKt.lazy((Function0)null.INSTANCE); String var0 = "companion init 1"; boolean var1 = false; System.out.println(var0); var0 = "companion init 2"; var1 = false; System.out.println(var0); } @Metadata( mv = {1, 1, 18}, bv = {1, 0, 3}, k = 1, d1 = {"\u0000\u0014
\u0002\u0018\u0002
\u0002\u0010\u0000
\u0002\b\u0002
\u0002\u0018\u0002
\u0002\b\u0005\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002R\u001b\u0010\u0003\u001a\u00020\u00048FX\u0086\u0084\u0002¢\u0006\f
\u0004\b\u0007\u0010\b\u001a\u0004\b\u0005\u0010\u0006¨\u0006\t"}, d2 = {"Lcom/androidtv/pos/Apple$Companion;", "", "()V", "instance", "Lcom/androidtv/pos/Apple;", "getInstance", "()Lcom/androidtv/pos/Apple;", "instance$delegate", "Lkotlin/Lazy;", "app"} ) public static final class Companion { @NotNull public final Apple getInstance() { Lazy var1 = Apple.instance$delegate; Apple.Companion var2 = Apple.Companion; Object var3 = null; boolean var4 = false; return (Apple)var1.getValue(); } private Companion() { } // $FF: synthetic method public Companion(DefaultConstructorMarker $constructor_marker) { this(); } } }

まとめ:伴生オブジェクトのコードはクラスロード時に実行されるため,伴生クラス初期化は先に実行され,さらに自身の構築方法が実行され,initコードは構築方法に統合されるが,構築方法の先頭に挿入される.