kotlinでのinit、constructor、companion object呼び出し順序
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コードは構築方法に統合されるが,構築方法の先頭に挿入される.