背景
Kotlin有主构造函数、次构造函数和init,他们的执行顺序是什么?
查看它们的执行顺序,最好的方法还是以打印为主。创建一个类,内部有主构造、次构造和一个init。
class Test {
constructor(name:String){
println("主构造函数")
}
constructor(name:String ,age:Int):this(name){
println("次构造函数")
}
init {
println("init....")
}
}
测试的时候,执行Test("Kt",0),我们看看执行打印。
结论
执行顺序: init -> 主构造函数 -> 次构造函数
为什么?
如果我答对了上面的问题,那么接下来面试官就会继续追问:
“为什么在Kotlin中,构造函数的执行顺序是init -> 主构造函数 -> 次构造函数?”
这个问题就需要去反编译为字节码,看看内部的流程是如何处理的。
#反编译
从上图看显而易见,当我们执行Test("Kt",0)时,会执行到次构造函数,但从次构造函数反编译的代码来看,会先执行this(name),指代的也就是主构造函数。而在主构造函数中,先会执行init,而后执行主构造函数内部的方法。
再加一个伴生对象呢?
如果你答出了以上两个问题,那么面试官还会继续追问:
“如果加上伴生对象,执行顺序又会是什么?为什么?“
实践出真知,在原有的测试代码上加上伴生对象。
companion object{
init {
println("伴生对象init")
}
}
依然先看下结论。
结论
执行顺序:伴生对象 -> init -> 主构造函数 -> 次构造函数
为什么?
#反编译
从上图可以看到,伴生对象被反编译后,其实是多了一个static final的内部类,而被static修饰执行是优先于普通代码块。