一 代码
kotlin:
package test.f
class Test1 {
}
class TestInit(s: String, i: Int) {
var name: String? = null
var age = 0
private var a :Int = 1
init {
this.name = s
this.age = i
println("init代码块: $name, $age")
}
}
转成java
// Test1.java
package test.f;
import kotlin.Metadata;
@Metadata(
mv = {2, 0, 0},
k = 1,
xi = 48,
d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0003"},
d2 = {"Ltest/f/Test1;", "", "()V", "untitled"}
)
public final class Test1 {
}
// TestInit.java
package test.f;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@Metadata(
mv = {2, 0, 0},
k = 1,
xi = 48,
d1 = {"\u0000\u0018\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\b\n\u0002\b\r\u0018\u00002\u00020\u0001B\u0015\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u0012\u0006\u0010\u0004\u001a\u00020\u0005¢\u0006\u0002\u0010\u0006R\u000e\u0010\u0007\u001a\u00020\u0005X\u0082\u000e¢\u0006\u0002\n\u0000R\u001a\u0010\b\u001a\u00020\u0005X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\t\u0010\n\"\u0004\b\u000b\u0010\fR\u001c\u0010\r\u001a\u0004\u0018\u00010\u0003X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u000e\u0010\u000f\"\u0004\b\u0010\u0010\u0011¨\u0006\u0012"},
d2 = {"Ltest/f/TestInit;", "", "s", "", "i", "", "(Ljava/lang/String;I)V", "a", "age", "getAge", "()I", "setAge", "(I)V", "name", "getName", "()Ljava/lang/String;", "setName", "(Ljava/lang/String;)V", "untitled"}
)
public final class TestInit {
@Nullable
private String name;
private int age;
private int a;
public TestInit(@NotNull String s, int i) {
Intrinsics.checkNotNullParameter(s, "s");
super();
this.a = 1;
this.name = s;
this.age = i;
String var3 = "init代码块: " + this.name + ", " + this.age;
System.out.println(var3);
}
@Nullable
public final String getName() {
return this.name;
}
public final void setName(@Nullable String var1) {
this.name = var1;
}
public final int getAge() {
return this.age;
}
public final void setAge(int var1) {
this.age = var1;
}
}
二 解释说明
在Kotlin中,类的初始化顺序严格按照代码中声明的顺序执行。对于提供的TestInit
类,执行顺序如下:
- 主构造函数参数处理:首先接收
s: String
和i: Int
。 - 属性初始化:按声明顺序依次初始化:
•name: String? = null
•age: Int = 0
•private var a: Int = 1
- 执行
init
块:最后运行init
中的代码,设置name
和age
的值,并打印信息。
为什么init
块在a
之后执行?
因为a
的声明和初始化(private var a: Int = 1
)出现在init
块之前。Kotlin会先处理所有在init
块之前声明的属性,再执行init
块。这保证了在init
块中访问a
时,它已经被正确初始化。
关键点:
• 声明顺序决定初始化顺序:属性和init
块的执行顺序完全由它们在类体中的位置决定。
• init
块属于初始化阶段:所有在init
块之前的属性会先初始化,确保init
块中的逻辑可以依赖这些已初始化的值。
三 总结
根据Kotlin的文档,当创建一个类的实例时,初始化顺序是这样的:
首先,主构造函数中的参数被处理;
接着,类体中声明的属性按照它们在代码中的顺序进行初始化;
然后,init块按照它们在类体中的出现顺序执行。
如果有多个init块,它们会按照顺序依次执行。
最后,次构造函数中的代码执行。