1. 程式人生 > >類變量和實例變量及其初始化

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

初始化 pos java 基本 定義 由於 調用 什麽 gpo

0.基本概念

  類變量是指java類中的static數據成員,實例變量則是指java類中的非static數據成員。由於類變量不需要創建一個對象即可訪問,而實例變量則必須與一個具體的對象對應,因此類變量和實例變量的初始化時機是不同的。本文主要關註以下3個問題:

  (1)什麽時候初始化類變量?什麽時候初始化實例變量?

  (2)什麽時候會同時初始化類變量和實例變量?

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

1.類變量初始化

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

  在下列情形下,如果一個java類中沒有被final修飾的類變量尚未初始化,那麽這些沒有被final修飾的類變量將會被初始化:

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

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

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

  初始化順序確定規則

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

  (2)static變量初始化的方式有兩種:定義時初始化和static代碼塊中初始化。因此,在類變量初始化時機時(上述的3種情形)java虛擬機會按照代碼中的順序依次執行static變量定義語句和static代碼塊。(兩種初始化方式的示例代碼如下)

  (3)如果該類有父類且父類的類變量沒有初始化,則先初始化父類的類變量。

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

  根據上述的初始化順序確定規則,可以確定初始化順序如下:

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

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

2.實例變量初始化

  實例變量初始化是在創建該類的對象時進行的,確定初始化順序的規則下:

  (1)如果創建該類的對象時該類的類變量尚未初始化,則先初始化類變量,載初始化實例變量;

  (2)如果該類有父類的話,則先創建一個父類對象;並且,如果父類類變量沒被初始化時,先初始化父類的類變量,再初始化父類的實例變量,再調用父類的默認構造器;

  (3)如果父類還有父類的話,根據(2)的規則以此類推,一直到根基類。

  根據上述初始化順序規則,可以確定的初始化順序如下:

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

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

3.實例

  

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