Java和Kotlin類的初始化順序
Java
Java程式初始化的順序:父類靜態變數 -> 父類靜態程式碼塊 -> 子類靜態變數 -> 子類靜態程式碼塊 -> 父類非靜態變數 -> 父類非靜態程式碼塊 -> 父類構造器 -> 子類非靜態變數 -> 子類非靜態程式碼塊 -> 子類構造器。
Java程式初始化一般遵循3個原則:
-
靜態物件(變數)先於非靜態物件(變數)初始化。其中靜態物件(變數)只初始化一次,因為static在jvm中只有一塊區域儲存,方法區(Method Area),
他之所以被稱為靜態是因為從程式建立到死亡他的地址值都不會改變,他只在class類物件初次載入時初始化,因此static只需要初始化一次,而非靜態物件(變數)可能會初始化很多次。 - 如果類之間存在繼承關係,那麼父類優先於子類進行初始化。
- 按照成員變數的定義順序進行初始化。即使變數定義散佈於方法之中,他們依然在任何方法(包括建構函式)被呼叫前先初始化
Kotlin
init
關鍵字==>java方法塊
companion object
伴生物件==>java靜態方法,伴生物件中的init
方法==>java靜態程式碼塊
internal open class ClassLoaderA { init { print("2") } init { print("3") } constructor() { print("5") } constructor(name: String) : this() { print("6") } constructor(name: String, id: String) { print("7") } open fun print() { print("4") } companion object { init { print("1") } } } internal class ClassLoaderB : ClassLoaderA("s") { init { print("b") } init { print("c") } override fun print() { print("d") } companion object { init { print("a") } } } object Hello { @JvmStatic fun main(args: Array<String>) { var classLoaderB: ClassLoaderA = ClassLoaderB() classLoaderB.print() println() classLoaderB = ClassLoaderB() }
//結果輸出 1a2356bcd 2356bc