得出結(jié)論
伴生對象 > 初始化代碼塊 > 構(gòu)造函數(shù)
(先>后)
代碼驗證
/**
* @data on 4/1/21 12:27 AM
* @auther KC
* @describe 探究Kotlin的init{}、構(gòu)造方法、伴生對象執(zhí)行順序
*/
class Coffee(val tease:String,val price:Double) {
//初始化代碼塊
init {
println("init1")
}
init {
println("init2")
}
//次構(gòu)造函數(shù)
constructor(tease:String) : this("bad",15.8){
println("constructor")
}
//伴生對象
companion object {
val flag = false
fun plus(num1:Int,num2:Int):Int {
return num1+num2
}
init {
println("companion object init1")
}
init {
println("companion object init2")
}
}
}
//主方法驗證
fun main(args:Array<String>){
val coffe = Coffee("e") //用于驗證
/**
* 驗證結(jié)果:先后排序
* companion object init1
* companion object init2
* init1
* init2
* constructor
* 總結(jié):伴生對象 > 初始化代碼塊 > 構(gòu)造函數(shù) (先>后)
*/
// val coffee = Coffee("good",9.9) //正常對象創(chuàng)建
// println(Coffee.flag) //用于驗證伴生對象調(diào)用
// println(Coffee.plus(1,1)) //用于驗證伴生對象調(diào)用
}
伴生對象的作用
通過的 Coffee.plus(1, 2) 和 Coffee.flag 代碼不難看出來,類似于 Java 中使用類訪問靜態(tài)成員的語法。因為 Kotlin 取消了 static 關(guān)鍵字,所以 Kotlin 引入伴生對象來彌補(bǔ)沒有靜態(tài)成員的不足。可見,伴生對象的主要作用就是為其所在的外部類模擬靜態(tài)成員。
init{}代碼塊
init塊和屬性的初始化是平級的,按代碼順序執(zhí)行。
與Java中的對比異同
kotlin的伴生對象(companion object)相當(dāng)于java中的靜態(tài)初始化塊(static {}), 只被同個類的所有實例的第一個實例執(zhí)行一次, 用于靜態(tài)成員變量初始化和初始化代碼。
kotlin的init代碼塊(init {})相當(dāng)于java的非靜態(tài)初始化塊({}), 每個類實例都會執(zhí)行, 且按先后順序執(zhí)行, 用于對多個構(gòu)造函數(shù)的代碼復(fù)用。
kotlin的主構(gòu)造函數(shù), 在java中沒有, 比次構(gòu)造函數(shù)(constructor)先執(zhí)行 (從次構(gòu)造函數(shù)需要繼承 : this()主構(gòu)造函數(shù)已經(jīng)可以推測是主構(gòu)造函數(shù)先執(zhí)行), 每個類實例都會執(zhí)行, 用于類成員變量的聲明/賦值, 由于沒有代碼塊, 所以不能做其他初始化邏輯。
kotlin的次構(gòu)造函數(shù)(constructor)相當(dāng)于java的構(gòu)造函數(shù), 函數(shù)簽名要跟主構(gòu)造函數(shù)不一樣, 否則報錯, 可以重載出多個次構(gòu)造函數(shù), 用于類初始化, 由于有代碼塊, 所以可以做其他初始化邏輯。