類變量和實例變量及其初始化

0.基本概念java

  類變量是指java類中的static數據成員,實例變量則是指java類中的非static數據成員。因爲類變量不須要建立一個對象便可訪問,而實例變量則必須與一個具體的對象對應,所以類變量和實例變量的初始化時機是不一樣的。本文主要關注如下3個問題:函數

  (1)何時初始化類變量?何時初始化實例變量?spa

  (2)何時會同時初始化類變量和實例變量?code

  (3)在(1)、(2)情形下各個類變量和實例變量的初始化順序?對象

1.類變量初始化blog

  1.1 類變量初始化方式繼承

  static變量初始化的方式有兩種:定義時初始化和static代碼塊中初始化。以下代碼所示:ci

1 class A(){  
2    public static int i = 1;//static變量初始化方式一:在定義時初始化
3    static{//static變量初始化方式二:在static代碼塊初始化static變量
4      System.out.println("statci 代碼塊");
5      }    
6  }

  1.2 類變量初始化時機編譯

  根據有無被final關鍵字修飾,類變量的初始化時機不一樣。被final關鍵字修飾的類變量在編譯時就已經被初始化被放置在常量池中了,而沒有被final修飾的類變量則在該類首次使用時被初始化。特別須要注意的是,類變量只在該類首次使用時被初始化,這意味着類變量只會被初始化一次。class

  在下列情形下,若是一個java類中沒有被final修飾的類變量還沒有初始化,那麼這些沒有被final修飾的類變量將會被初始化:

  (1)訪問該類中沒有被final修飾的類變量時;

  (2)設置該類中沒有被final修飾的類變量時;

  (3)調用該類的static方法。

  1.2 類變量初始化順序

  類變量初始化會遵循如下三個原則:

  (1)在上述3個情形下,首先會初始化該類中全部沒有被final修飾的類變量,而後再執行對應的操做;

  (2)按照代碼中的順序依次執行static變量定義語句和static代碼塊;

  (3)若是該類有父類且父類的類變量沒有初始化,則先初始化父類的類變量;

  (4)若是父類還有父類的話,根據(3)的規則,以此類推。

  根據上述原則,能夠肯定類變量初始化順序以下:

//沒有繼承的情形
static變量初始化和static代碼塊

//有繼承的情形
1.父類的static變量初始化和static代碼塊
2.子類的static變量初始化和static代碼塊

/*備註:
類變量初始化只有一次,若是某個java類的類變量已經被初始化過了,則上述過程當中的類變量初始化將再也不執行
*/

 

2.實例變量初始化

  2.1 實例變量初始化方式

  與類變量初始化方式相似,實例變量初始化方式也有兩種:定義時初始化和代碼塊初始化。示例以下:

1  class A(){  
2    public static int i = 1;//實例變量初始化方式一:在定義時初始化
3 
4    {//實例變量初始化方式二:在代碼塊初始化實例變量
5      System.out.println("代碼塊");
6      }    
7  }

  2.2 實例變量初始化時機和順序

  實例變量初始化是在建立該類的對象時進行的,初始化時遵循的原則是:

  (1)按照代碼中的順序依次執行實例變量定義語句和實例變量代碼塊;

  (2)若是建立該類的對象時該類的類變量還沒有初始化,則先初始化類變量,再初始化實例變量;

  (3)若是該類有父類的話,則先建立一個父類對象;而且,若是父類類變量沒被初始化時,先初始化父類的類變量,再初始化父類的實例變量,再調用父類的默認構造器;

  (4)若是父類還有父類的話,根據(3)的規則以此類推,一直到根基類。

  根據上述原則易知,實例變量初始化以前可能會先初始化類變量(這是特別須要留意的一點)。初始化順序以下:

//沒有繼承的情形(且該類的類變量未被初始化)
1.static變量初始化和static代碼塊
2.實例變量初始化和實例變量初始化代碼塊
3.構造函數

//有繼承的情形(且該類和父類的類變量未被初始化)
1.父類的static變量初始化和static代碼塊
2.子類的static變量初始化和static代碼塊
3.父類的實例變量初始化和實例變量初始化代碼塊
4.父類的構造函數
5.子類的實例變量初始化和實例變量初始化代碼塊
6.子類構造函數

/*備註:
類變量初始化只有一次,若是某個java類的類變量已經被初始化過了,則上述過程當中的類變量初始化將再也不執行
*/

3.小結

  你們看完若是還不太明白類變量和實例變量的初始化時機和順序,能夠親自去寫一個demo試試,實踐才能出真知嘛!

  在這裏,只強調兩點:

  (1)類變量只會初始化一次;

  (2)類變量和實例變量的初始化時機是不一樣的,類變量初始化在首次使用該類的時候進行,實例變量的初始化在建立該類的每一個對象時都會進行。

相關文章
相關標籤/搜索