clinit和init

xiaoyuyami發表於2020-11-23

<clinit>方法是類構造器方法,只對類方法(static域和static程式碼塊)進行初始化,<clinit>方法是在:載入->連結->初始化的初始化階段進行的。Java在編譯之後會在位元組碼檔案中生成<clinit>方法,將靜態域和靜態程式碼塊收斂到<clinit>方法中,收斂順序為:

  1. 父類靜態變數初始化(預設值0或null)
  2. 父類靜態語句塊初始化
  3. 子類靜態變數初始化
  4. 子類靜態語句塊初始化

<init>方法是例項構造器,在物件被建立(new)時,進行例項化操作的方法。並且子類的<init>方法會首先呼叫父類的<init>方法(即在constructor中首先呼叫super)。Java在編譯之後會在位元組碼檔案中生成<init>方法,該例項構造器會將變數,語句塊初始化,呼叫父類的構造器等操作收斂到<init>方法中,收斂順序為:

  1. 父類變數初始化(這裡的初始化,就是賦予預設值)
  2. 父類語句塊初始化
  3. 父類建構函式(賦予變數使用者值)
  4. 子類變數初始化
  5. 子類語句塊初始化
  6. 子類建構函式

<clinit>方法的的執行時間一定早於<init>,因為<clinit>方法是在類初始化過程中執行的,而<init>方法是在物件例項化時執行的。

所以,整個順序就是:

  1. 父類靜態變數初始化
  2. 父類靜態語句塊初始化
  3. 子類靜態變數初始化
  4. 子類靜態語句塊初始化
  5. 父類變數初始化(初始化非靜態成員變數(賦予預設值))
  6. 父類語句塊初始化
  7. 父類建構函式(建構函式中賦值(變數使用者值))
  8. 子類變數初始化
  9. 子類語句塊初始化
  10. 子類建構函式

相關文章