java基礎-初始化與清理-成員初始化

破羅蘭心發表於2020-12-09

java的成員初始化

java中保證:所有的變數在使用前都能得到恰當的初始化。

一.方法中的區域性變數的初始化

         對於方法中的區域性變數,若在使用前沒有進行初始化,則編譯時會報錯,來確保每一個區域性變數的初始化。

二.類的資料成員初始化

         類的資料成員(欄位),也稱為全域性變數,若沒有初始化,那麼在類的物件初始化時,便會自動給其賦予初值,來確保其在使用前

已經被初始化了。當類的物件初始化時,對於基本資料型別的成員變數,會根據其基本型別來賦予初值。對於非基本資料型別的成員變

量,如一個物件的引用時,會獲得初始值null。測試如下:

結果為:

可以看到每一個成員在物件初始化時都被賦予了初值(char值為0,所以顯示為空白)。

如果想要為某個成員賦初始值的話,有幾種方式:

1.定義該類成員變數時直接賦予初值。這個初值是某個確定的值,也可以是某個方法返回的值,這個方法可以帶引數也可以不帶,但是帶了引數的話

引數必須是已經被初始化了的。例如:

這樣的初始化方法直接,但是當建立這個類的物件時,所有物件都會具有相同的成員初值。

2.構造器初始化。在執行時呼叫構造器或某些方法來進行初始化,這種初始化方式很靈活,但是需要注意的是:無法阻止自動初始化的進行,它將在構造器

呼叫之前發生。例如:

對於所有基本型別和物件引用,包括在定義時已經指定初值的變數,這種情況都是成立的,所以編譯器不會強制你一定要在構造器的某個地方或在使用他們之前

對他們進行初始化,因為初始化早已經得到保證。

 

三.類的成員變數(全域性變數)的初始化順序

        在類的內部,定義成員變數的先後順序決定了他們初始化的順序,即便是變數散佈於類中方法之間,它們仍然會在任何方法(包括構造器)被呼叫之前得到

初始化。例如:

輸出結果為:

解釋:在House中,故意把Window物件的定義散佈到各處,結果,它們全都會在呼叫構造器或者其他方法之前得到初始化,然後再進行House構造器的初始化,在初始化時

w3在構造器中再次被初始化。所以w3這個引用會被初始化2次,第一次在呼叫構造器之前,第二次在呼叫期間(第一次引用指向的物件將被丟棄,並將被垃圾回收器回收)。

在上面的例子中,試想,如果定義了一個過載構造器,它沒有初始化w3,同時在w3的定義裡也沒有指定預設值,那會產生什麼後果呢?這裡我們將程式碼改一下

這裡我們列印下window3的值是多少,輸出結果為:

雖然這裡的window3值為null,但是證明了它確實被初始化了,但是沒有通過構造器初始化,說明它是自動初始化的。也證明了構造器初始化無法阻止自動初始化的進行。

 

四.靜態資料的初始化

      無論建立多少個物件,靜態資料都只佔用一份儲存區域。static關鍵字不能作用於區域性變數,因此它只能作用於域(全域性)。如果一個域是靜態的基本型別域,且也沒有

對它進行初始化,那麼它將會獲得基本型別的標準初值。如果它是一個物件引用,那麼它的預設初值就是null。如果在定義處進行初始化,那麼採取的方法和非靜態資料沒有

什麼不同。

那麼靜態儲存區域是什麼時候初始化的呢?看下面的例子:

TicketNum類使得以看到類的建立,TicketPrice類和TicketPrd類在它們的類定義中加入了TicketNum型別的靜態資料成員num1,num2,num4,num5,

同時,TicketPrd類在定義靜態資料成員之前,先定義了一個非靜態資料成員num3。此時,來看下輸出:

從輸出結果來看,初始化的順序是先靜態物件(如果它們尚未因前面的物件建立過程而被初始化),而後是非靜態物件。要執行main()(靜態方法),必須載入

StaticInitOrderTest類,然後其靜態域TicketPrice和TicketPrd被初始化,這將導致它們對應的類也被載入,並且由於它們都包含靜態的TicketNum物件,因此TicketNum

類也被載入,這樣,在這個程式中的所有類都在main()開始之前就都被載入了。

所以總結一下物件的建立過程,假設有個名為Dog的類:

1.即使沒有顯式的使用static關鍵字,構造器實際上也是靜態方法,因此當首次建立型別為Dog的物件時,或者Dog類的靜態方法/靜態域首次被訪問時,java直譯器必須

查詢類路徑,以定位Dog.class檔案。

2.然後載入Dog.class(這將建立一個Class物件),有關靜態初始化的所有動作都會進行,因此靜態初始化只在Class物件首次載入時進行一次。

3.當用new Dog()建立物件的時候,首先將在堆上為Dog物件分配足夠的儲存空間。

4.這塊儲存空間會被清零,這就自動的將Dog物件中的所有基本型別資料都設定成了預設值(對數字來說就是0,對布林型和字元型也相同),而引用則被設定成了null。

5.執行所有出現於欄位定義處的初始化動作。

6.執行構造器。

 

五.顯示的靜態初始化(靜態程式碼塊的初始化)

java允許將多個靜態初始化動作組織成一個特殊的“靜態子句”,也稱靜態程式碼塊,它的初始化動作和上面的靜態初始化動作一樣,當首次生成這個類的一個物件或者首次訪問

屬於那個類的靜態資料成員時(即使從未生成過那個類的物件),靜態程式碼塊將進行初始化,並且這段程式碼僅執行一次。例如:

輸出為:

 

 

 

相關文章