例子
class Test(val name: String) {//1 类名后面定义的主构造函数,数量<=1
init {//2 init代码块
println("init")
}
private var age: Int? = null
constructor(name: String, age: Int) : this(name) {//3 次构造函数,数量>=0
println("second constructor")
this.age = age
}
}
- 注释1:主构造函数,数量<=1,如果都没有定义主、次构造函数,那么就会有一个默认无参的构造函数可以调用;
- 注释2:初始化代码块,一般用来做初始化工作;
- 注释3:次构造函数,数量>=0;
反编译看下
因为Kotlin有很多语法糖,在无法直接点击看源码的情况下,可以通过反编译的方式来窥探原理;
public final class Test {
private Integer age;
@NotNull
private final String name;
@NotNull
public final String getName() {
return this.name;
}
public Test(@NotNull String name) {//1
Intrinsics.checkNotNullParameter(name, "name");
super();
this.name = name;
String var2 = "init";
boolean var3 = false;
System.out.println(var2);//2
}
public Test(@NotNull String name, int age) {//3
Intrinsics.checkNotNullParameter(name, "name");
this(name);
String var3 = "second constructor";
boolean var4 = false;
System.out.println(var3);
this.age = age;
}
}
- 注释1:对应主构造函数;
- 注释2:对应init代码块;
- 注释3:对应次构造函数;
到这里,其实大概就能知道执行顺序了
- 通过主构造函数Test("yang")构建对象,会先执行属性赋值操作"this.name = name",再执行init代码块逻辑;
- 通过次构造函数Test("yang",30)构建对象,会先执行属性赋值操作"this.name = name",再执行init代码块逻辑,在执行属性赋值操作"this.age = age";
问题来了
通过次构造函数Test("yang",30)构建对象,age这个属性有值吗?
答案:是没有的,因为age赋值是在init之后。
总结
执行顺序:主构造函数-init代码块-次构造函数。
以上分析有不对的地方,请指出,互相学习,谢谢哦!
网友评论